aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/src/main/java/github/daneren2005/dsub/adapter/DetailsAdapter.java62
-rw-r--r--app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java29
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java57
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java12
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SelectPlaylistFragment.java60
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SelectPodcastsFragment.java30
-rw-r--r--app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java178
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/OfflineMusicService.java46
-rw-r--r--app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java2
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/FileUtil.java19
-rw-r--r--app/src/main/java/github/daneren2005/dsub/util/Util.java32
-rw-r--r--app/src/main/res/layout/details_item.xml28
-rw-r--r--app/src/main/res/menu/select_album_context.xml40
-rw-r--r--app/src/main/res/menu/select_album_context_offline.xml30
-rw-r--r--app/src/main/res/menu/select_artist_context.xml40
-rw-r--r--app/src/main/res/menu/select_artist_context_offline.xml30
-rw-r--r--app/src/main/res/menu/select_bookmark_context.xml12
-rw-r--r--app/src/main/res/menu/select_playlist_context.xml15
-rw-r--r--app/src/main/res/menu/select_playlist_context_offline.xml14
-rw-r--r--app/src/main/res/menu/select_podcast_episode_context.xml12
-rw-r--r--app/src/main/res/menu/select_podcast_episode_context_offline.xml8
-rw-r--r--app/src/main/res/values-de/strings.xml8
-rw-r--r--app/src/main/res/values-es/strings.xml8
-rw-r--r--app/src/main/res/values-fr/strings.xml6
-rw-r--r--app/src/main/res/values-hu/strings.xml6
-rw-r--r--app/src/main/res/values-ru/strings.xml6
-rw-r--r--app/src/main/res/values/strings.xml44
27 files changed, 399 insertions, 435 deletions
diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/DetailsAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/DetailsAdapter.java
new file mode 100644
index 00000000..efafe27a
--- /dev/null
+++ b/app/src/main/java/github/daneren2005/dsub/adapter/DetailsAdapter.java
@@ -0,0 +1,62 @@
+/*
+ This file is part of Subsonic.
+ Subsonic is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+ Subsonic is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+ You should have received a copy of the GNU General Public License
+ along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
+ Copyright 2015 (C) Scott Jackson
+*/
+
+package github.daneren2005.dsub.adapter;
+
+import android.content.Context;
+import android.text.SpannableString;
+import android.text.method.LinkMovementMethod;
+import android.text.util.Linkify;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import java.util.List;
+
+import github.daneren2005.dsub.R;
+
+public class DetailsAdapter extends ArrayAdapter<String> {
+ private List<String> headers;
+ private List<String> details;
+
+ public DetailsAdapter(Context context, int layout, List<String> headers, List<String> details) {
+ super(context, layout, headers);
+
+ this.headers = headers;
+ this.details = details;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent){
+ View view;
+ if(convertView == null) {
+ view = LayoutInflater.from(getContext()).inflate(R.layout.details_item, null);
+ } else {
+ view = convertView;
+ }
+
+ TextView nameView = (TextView) view.findViewById(R.id.detail_name);
+ TextView detailsView = (TextView) view.findViewById(R.id.detail_value);
+
+ nameView.setText(headers.get(position));
+
+ detailsView.setText(details.get(position));
+ Linkify.addLinks(detailsView, Linkify.ALL);
+
+ return view;
+ }
+}
diff --git a/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java b/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java
index 9d577409..3f6086d5 100644
--- a/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java
+++ b/app/src/main/java/github/daneren2005/dsub/adapter/SectionAdapter.java
@@ -178,9 +178,7 @@ public abstract class SectionAdapter<T> extends RecyclerView.Adapter<UpdateViewH
if(sections.size() == 1 && !singleSectionHeader) {
T item = sections.get(0).get(position);
onBindViewHolder(holder, item, getItemViewType(position));
- if(updateView.isCheckable()) {
- setChecked(updateView, selected.contains(item));
- }
+ postBindView(updateView, item);
holder.setItem(item);
return;
}
@@ -199,9 +197,7 @@ public abstract class SectionAdapter<T> extends RecyclerView.Adapter<UpdateViewH
T item = section.get(position - subPosition - headerOffset);
onBindViewHolder(holder, item, getItemViewType(item));
- if(updateView.isCheckable()) {
- setChecked(updateView, selected.contains(item));
- }
+ postBindView(updateView, item);
holder.setItem(item);
return;
}
@@ -214,6 +210,27 @@ public abstract class SectionAdapter<T> extends RecyclerView.Adapter<UpdateViewH
}
}
+ private void postBindView(UpdateView updateView, T item) {
+ if(updateView.isCheckable()) {
+ setChecked(updateView, selected.contains(item));
+ }
+
+ View moreButton = updateView.findViewById(R.id.more_button);
+ if(moreButton == null) {
+ moreButton = updateView.findViewById(R.id.item_more);
+ }
+ if(moreButton != null) {
+ PopupMenu popup = new PopupMenu(context, moreButton);
+ Menu menu = popup.getMenu();
+ onItemClickedListener.onCreateContextMenu(popup.getMenu(), popup.getMenuInflater(), updateView, item);
+ if(menu.size() == 0) {
+ moreButton.setVisibility(View.GONE);
+ } else {
+ moreButton.setVisibility(View.VISIBLE);
+ }
+ }
+ }
+
@Override
public int getItemCount() {
if(sections.size() == 1 && !singleSectionHeader) {
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java
index 87da5d9c..d25315ac 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/MainFragment.java
@@ -1,5 +1,6 @@
package github.daneren2005.dsub.fragments;
+import android.content.res.Resources;
import android.support.v7.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
@@ -277,32 +278,54 @@ public class MainFragment extends SelectRecyclerFragment<Integer> {
}
private void showAboutDialog() {
- new LoadingTask<String>(context) {
+ new LoadingTask<Void>(context) {
+ Long[] used;
+ long bytesTotalFs;
+ long bytesAvailableFs;
+
@Override
- protected String doInBackground() throws Throwable {
+ protected Void doInBackground() throws Throwable {
File rootFolder = FileUtil.getMusicDirectory(context);
StatFs stat = new StatFs(rootFolder.getPath());
- long bytesTotalFs = (long) stat.getBlockCount() * (long) stat.getBlockSize();
- long bytesAvailableFs = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
-
- Pair<Long, Long> used = FileUtil.getUsedSize(context, rootFolder);
-
- return getResources().getString(R.string.main_about_text,
- context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName,
- used.getFirst(),
- Util.formatLocalizedBytes(used.getSecond(), context),
- Util.formatLocalizedBytes(Util.getCacheSizeMB(context) * 1024L * 1024L, context),
- Util.formatLocalizedBytes(bytesAvailableFs, context),
- Util.formatLocalizedBytes(bytesTotalFs, context));
+ bytesTotalFs = (long) stat.getBlockCount() * (long) stat.getBlockSize();
+ bytesAvailableFs = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize();
+
+ used = FileUtil.getUsedSize(context, rootFolder);
+ return null;
}
@Override
- protected void done(String msg) {
+ protected void done(Void result) {
+ List<Integer> headers = new ArrayList<>();
+ List<String> details = new ArrayList<>();
+
+ headers.add(R.string.details_author);
+ details.add("Scott Jackson");
+
+ headers.add(R.string.details_email);
+ details.add("dsub.android@gmail.com");
+
try {
- Util.info(context, R.string.main_about_title, msg);
+ headers.add(R.string.details_version);
+ details.add(context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName);
} catch(Exception e) {
- Util.toast(context, "Failed to open dialog");
+ details.add("");
}
+
+ Resources res = context.getResources();
+ headers.add(R.string.details_files_cached);
+ details.add(Long.toString(used[0]));
+
+ headers.add(R.string.details_files_permanent);
+ details.add(Long.toString(used[1]));
+
+ headers.add(R.string.details_used_space);
+ details.add(res.getString(R.string.details_of, Util.formatLocalizedBytes(used[2], context), Util.formatLocalizedBytes(Util.getCacheSizeMB(context) * 1024L * 1024L, context)));
+
+ headers.add(R.string.details_available_space);
+ details.add(res.getString(R.string.details_of, Util.formatLocalizedBytes(bytesAvailableFs, context), Util.formatLocalizedBytes(bytesTotalFs, context)));
+
+ Util.showDetailsDialog(context, R.string.main_about_title, headers, details);
}
}.execute();
}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
index 2ab8316c..555e308e 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java
@@ -360,18 +360,6 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Section
}
@Override
public boolean onContextItemSelected(MenuItem menuItem, UpdateView<Entry> updateView, Entry entry) {
- if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_PLAY_NOW_AFTER, false) && menuItem.getItemId() == R.id.song_menu_play_now) {
- List<Entry> songs = new ArrayList<Entry>();
- songs.add(entry);
- Iterator it = entries.listIterator(entries.indexOf(entry));
- while(it.hasNext()) {
- songs.add((Entry) it.next());
- }
-
- playNow(songs);
- return true;
- }
-
if(onContextItemSelected(menuItem, entry)) {
return true;
}
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectPlaylistFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectPlaylistFragment.java
index 5b7e68a6..b1587e24 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectPlaylistFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectPlaylistFragment.java
@@ -68,40 +68,13 @@ public class SelectPlaylistFragment extends SelectRecyclerFragment<Playlist> {
@Override
public boolean onContextItemSelected(MenuItem menuItem, UpdateView<Playlist> updateView, Playlist playlist) {
- SubsonicFragment fragment;
- Bundle args;
- FragmentTransaction trans;
switch (menuItem.getItemId()) {
- case R.id.playlist_menu_download:
- downloadPlaylist(playlist.getId(), playlist.getName(), false, true, false, false, true);
- break;
case R.id.playlist_menu_sync:
syncPlaylist(playlist);
break;
case R.id.playlist_menu_stop_sync:
stopSyncPlaylist(playlist);
break;
- case R.id.playlist_menu_play_now:
- fragment = new SelectDirectoryFragment();
- args = new Bundle();
- args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID, playlist.getId());
- args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME, playlist.getName());
- args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true);
- fragment.setArguments(args);
-
- replaceFragment(fragment);
- break;
- case R.id.playlist_menu_play_shuffled:
- fragment = new SelectDirectoryFragment();
- args = new Bundle();
- args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID, playlist.getId());
- args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME, playlist.getName());
- args.putBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, true);
- args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true);
- fragment.setArguments(args);
-
- replaceFragment(fragment);
- break;
case R.id.playlist_menu_delete:
deletePlaylist(playlist);
break;
@@ -213,12 +186,33 @@ public class SelectPlaylistFragment extends SelectRecyclerFragment<Playlist> {
}
private void displayPlaylistInfo(final Playlist playlist) {
- String message = "Owner: " + playlist.getOwner() + "\nComments: " +
- ((playlist.getComment() == null) ? "" : playlist.getComment()) +
- "\nSong Count: " + playlist.getSongCount() +
- ((playlist.getPublic() == null) ? "" : ("\nPublic: " + playlist.getPublic())) +
- "\nCreated: " + Util.formatDate(context, playlist.getCreated());
- Util.info(context, playlist.getName(), message);
+ List<Integer> headers = new ArrayList<>();
+ List<String> details = new ArrayList<>();
+
+ if(playlist.getOwner() != null) {
+ headers.add(R.string.details_owner);
+ details.add(playlist.getOwner());
+ }
+
+ if(playlist.getComment() != null) {
+ headers.add(R.string.details_comments);
+ details.add(playlist.getComment());
+ }
+
+ headers.add(R.string.details_song_count);
+ details.add(playlist.getSongCount());
+
+ if(playlist.getPublic() != null) {
+ headers.add(R.string.details_public);
+ details.add(Boolean.toString(playlist.getPublic()));
+ }
+
+ if(playlist.getCreated() != null) {
+ headers.add(R.string.details_created);
+ details.add(Util.formatDate(context, playlist.getCreated()));
+ }
+
+ Util.showDetailsDialog(context, R.string.details_title_playlist, headers, details);
}
private void updatePlaylistInfo(final Playlist playlist) {
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SelectPodcastsFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SelectPodcastsFragment.java
index f8afce6e..381453c0 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SelectPodcastsFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SelectPodcastsFragment.java
@@ -214,13 +214,29 @@ public class SelectPodcastsFragment extends SelectRecyclerFragment<PodcastChanne
}
private void displayPodcastInfo(final PodcastChannel channel) {
- String message = ((channel.getName()) == null ? "" : "Title: " + channel.getName()) +
- "\nURL: " + channel.getUrl() +
- "\nStatus: " + channel.getStatus() +
- ((channel.getErrorMessage()) == null ? "" : "\nError Message: " + channel.getErrorMessage()) +
- ((channel.getDescription()) == null ? "" : "\n\nDescription: " + channel.getDescription());
-
- Util.info(context, channel.getName(), message);
+ List<Integer> headers = new ArrayList<>();
+ List<String> details = new ArrayList<>();
+
+ if(channel.getName() != null) {
+ headers.add(R.string.details_title);
+ details.add(channel.getName());
+ }
+
+ headers.add(R.string.details_url);
+ details.add(channel.getUrl());
+ headers.add(R.string.details_status);
+ details.add(channel.getStatus());
+
+ if(channel.getErrorMessage() != null) {
+ headers.add(R.string.details_error);
+ details.add(channel.getErrorMessage());
+ }
+ if(channel.getDescription() != null) {
+ headers.add(R.string.details_description);
+ details.add(channel.getDescription());
+ }
+
+ Util.showDetailsDialog(context, R.string.details_title_podcast, headers, details);
}
private void deletePodcast(final PodcastChannel channel) {
diff --git a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java
index 438649c3..6925b2da 100644
--- a/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java
+++ b/app/src/main/java/github/daneren2005/dsub/fragments/SubsonicFragment.java
@@ -241,9 +241,8 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
} else if(selected instanceof Artist) {
Artist artist = (Artist) selected;
if(Util.isOffline(context)) {
- menuInflater.inflate(R.menu.select_artist_context_offline, menu);
- }
- else {
+ // menuInflater.inflate(R.menu.select_artist_context_offline, menu);
+ } else {
menuInflater.inflate(R.menu.select_artist_context, menu);
menu.findItem(R.id.artist_menu_star).setTitle(artist.isStarred() ? R.string.common_unstar : R.string.common_star);
@@ -281,56 +280,6 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
if(!prefs.getBoolean(Constants.PREFERENCES_KEY_MENU_RATING, true)) {
menu.setGroupVisible(R.id.hide_rating, false);
}
-
- if(!Util.isOffline(context)) {
- // If we are looking at a standard song view, get downloadFile to cache what options to show
- if(updateView instanceof SongView) {
- SongView songView = (SongView) updateView;
- DownloadFile downloadFile = songView.getDownloadFile();
-
- try {
- if(downloadFile != null) {
- if(downloadFile.isWorkDone()) {
- // Remove permanent cache menu if already perma cached
- if(downloadFile.isSaved()) {
- menu.removeItem(R.id.song_menu_pin);
- }
-
- // Remove cache option no matter what if already downloaded
- menu.removeItem(R.id.song_menu_download);
- } else {
- // Remove delete option if nothing to delete
- menu.removeItem(R.id.song_menu_delete);
- }
- }
- } catch(Exception e) {
- Log.w(TAG, "Failed to lookup downloadFile info", e);
- }
- }
- // Apply similar logic to album views
- else if(updateView instanceof AlbumView || updateView instanceof ArtistView || updateView instanceof ArtistEntryView) {
- File folder = null;
- int id = 0;
- if(updateView instanceof AlbumView) {
- folder = ((AlbumView) updateView).getFile();
- id = R.id.album_menu_delete;
- } else if(updateView instanceof ArtistView) {
- folder = ((ArtistView) updateView).getFile();
- id = R.id.artist_menu_delete;
- } else if(updateView instanceof ArtistEntryView) {
- folder = ((ArtistEntryView) updateView).getFile();
- id = R.id.artist_menu_delete;
- }
-
- try {
- if(folder != null && !folder.exists()) {
- menu.removeItem(id);
- }
- } catch(Exception e) {
- Log.w(TAG, "Failed to lookup album directory info", e);
- }
- }
- }
}
protected void recreateContextMenu(Menu menu) {
@@ -355,60 +304,12 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
songs.add(entry);
switch (menuItem.getItemId()) {
- case R.id.artist_menu_play_now:
- downloadRecursively(artist.getId(), false, false, true, false, false);
- break;
- case R.id.artist_menu_play_shuffled:
- downloadRecursively(artist.getId(), false, false, true, true, false);
- break;
- case R.id.artist_menu_play_next:
- downloadRecursively(artist.getId(), false, true, false, false, false, true);
- break;
- case R.id.artist_menu_play_last:
- downloadRecursively(artist.getId(), false, true, false, false, false);
- break;
- case R.id.artist_menu_download:
- downloadRecursively(artist.getId(), false, true, false, false, true);
- break;
- case R.id.artist_menu_pin:
- downloadRecursively(artist.getId(), true, true, false, false, true);
- break;
- case R.id.artist_menu_delete:
- deleteRecursively(artist);
- break;
case R.id.artist_menu_star:
toggleStarred(artist);
break;
- case R.id.album_menu_play_now:
- artistOverride = true;
- downloadRecursively(entry.getId(), false, false, true, false, false);
- break;
- case R.id.album_menu_play_shuffled:
- artistOverride = true;
- downloadRecursively(entry.getId(), false, false, true, true, false);
- break;
- case R.id.album_menu_play_next:
- artistOverride = true;
- downloadRecursively(entry.getId(), false, true, false, false, false, true);
- break;
- case R.id.album_menu_play_last:
- artistOverride = true;
- downloadRecursively(entry.getId(), false, true, false, false, false);
- break;
- case R.id.album_menu_download:
- artistOverride = true;
- downloadRecursively(entry.getId(), false, true, false, false, true);
- break;
- case R.id.album_menu_pin:
- artistOverride = true;
- downloadRecursively(entry.getId(), true, true, false, false, true);
- break;
case R.id.album_menu_star:
toggleStarred(entry);
break;
- case R.id.album_menu_delete:
- deleteRecursively(entry);
- break;
case R.id.album_menu_info:
displaySongInfo(entry);
break;
@@ -418,21 +319,9 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
case R.id.album_menu_share:
createShare(songs);
break;
- case R.id.song_menu_play_now:
- playNow(songs);
- break;
- case R.id.song_menu_play_next:
- getDownloadService().download(songs, false, false, true, false);
- break;
- case R.id.song_menu_play_last:
- getDownloadService().download(songs, false, false, false, false);
- break;
case R.id.song_menu_download:
getDownloadService().downloadBackground(songs, false);
break;
- case R.id.song_menu_pin:
- getDownloadService().downloadBackground(songs, true);
- break;
case R.id.song_menu_delete:
getDownloadService().delete(songs);
break;
@@ -1262,7 +1151,6 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}.execute();
}
- @TargetApi(Build.VERSION_CODES.GINGERBREAD_MR1)
public void displaySongInfo(final Entry song) {
Integer duration = null;
Integer bitrate = null;
@@ -1302,55 +1190,83 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR
}
}
- String msg = "";
+ List<Integer> headers = new ArrayList<>();
+ List<String> details = new ArrayList<>();
if(song instanceof PodcastEpisode) {
- msg += "Podcast: " + song.getArtist() + "\nStatus: " + ((PodcastEpisode)song).getStatus();
+ headers.add(R.string.details_podcast);
+ details.add(song.getArtist());
+
+ headers.add(R.string.details_status);
+ details.add(((PodcastEpisode)song).getStatus());
} else if(!song.isVideo()) {
if(song.getArtist() != null && !"".equals(song.getArtist())) {
- msg += "Artist: " + song.getArtist();
+ headers.add(R.string.details_artist);
+ details.add(song.getArtist());
}
if(song.getAlbum() != null && !"".equals(song.getAlbum())) {
- msg += "\nAlbum: " + song.getAlbum();
+ headers.add(R.string.details_album);
+ details.add(song.getAlbum());
}
}
if(song.getTrack() != null && song.getTrack() != 0) {
- msg += "\nTrack: " + song.getTrack();
+ headers.add(R.string.details_track);
+ details.add(Integer.toString(song.getTrack()));
}
if(song.getGenre() != null && !"".equals(song.getGenre())) {
- msg += "\nGenre: " + song.getGenre();
+ headers.add(R.string.details_genre);
+ details.add(song.getGenre());
}
if(song.getYear() != null && song.getYear() != 0) {
- msg += "\nYear: " + song.getYear();
+ headers.add(R.string.details_year);
+ details.add(Integer.toString(song.getYear()));
}
if(!Util.isOffline(context) && song.getSuffix() != null) {
- msg += "\nServer Format: " + song.getSuffix();
+ headers.add(R.string.details_server_format);
+ details.add(song.getSuffix());
+
if(song.getBitRate() != null && song.getBitRate() != 0) {
- msg += "\nServer Bitrate: " + song.getBitRate() + " kbps";
+ headers.add(R.string.details_server_bitrate);
+ details.add(song.getBitRate() + " kbps");
}
}
if(format != null && !"".equals(format)) {
- msg += "\nCached Format: " + format;
+ headers.add(R.string.details_cached_format);
+ details.add(format);
}
if(bitrate != null && bitrate != 0) {
- msg += "\nCached Bitrate: " + bitrate + " kbps";
+ headers.add(R.string.details_cached_bitrate);
+ details.add(bitrate + " kbps");
}
if(size != 0) {
- msg += "\nSize: " + Util.formatLocalizedBytes(size, context);
+ headers.add(R.string.details_size);
+ details.add(Util.formatLocalizedBytes(size, context));
}
if(song.getDuration() != null && song.getDuration() != 0) {
- msg += "\nLength: " + Util.formatDuration(song.getDuration());
+ headers.add(R.string.details_length);
+ details.add(Util.formatDuration(song.getDuration()));
}
if(song.getBookmark() != null) {
- msg += "\nBookmark Position: " + Util.formatDuration(song.getBookmark().getPosition() / 1000);
+ headers.add(R.string.details_bookmark_position);
+ details.add(Util.formatDuration(song.getBookmark().getPosition() / 1000));
}
if(song.getRating() != 0) {
- msg += "\nRating: " + song.getRating() + " stars";
+ headers.add(R.string.details_rating);
+ details.add(song.getRating() + " stars");
}
if(song instanceof PodcastEpisode) {
- msg += "\n\nDescription: " + song.getAlbum();
+ headers.add(R.string.details_description);
+ details.add(song.getAlbum());
}
- Util.info(context, song.getTitle(), msg);
+ int title;
+ if(song.isDirectory()) {
+ title = R.string.details_title_album;
+ } else if(song instanceof PodcastEpisode) {
+ title = R.string.details_title_podcast;
+ } else {
+ title = R.string.details_title_song;
+ }
+ Util.showDetailsDialog(context, title, headers, details);
}
protected void playVideo(Entry entry) {
diff --git a/app/src/main/java/github/daneren2005/dsub/service/OfflineMusicService.java b/app/src/main/java/github/daneren2005/dsub/service/OfflineMusicService.java
index b4105d07..8ebf4c13 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/OfflineMusicService.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/OfflineMusicService.java
@@ -382,6 +382,42 @@ public class OfflineMusicService implements MusicService {
String id = file.getName();
String filename = server + ": " + FileUtil.getBaseName(id);
Playlist playlist = new Playlist(server, filename);
+
+ Reader reader = null;
+ BufferedReader buffer = null;
+ try {
+ int songCount = 0;
+ reader = new FileReader(file);
+ buffer = new BufferedReader(reader);
+
+ String line = buffer.readLine();
+ while( (line = buffer.readLine()) != null ){
+ // No matter what, end file can't have .complete in it
+ line = line.replace(".complete", "");
+ File entryFile = new File(line);
+
+ // Don't add file to playlist if it doesn't exist as cached or pinned!
+ File checkFile = entryFile;
+ if(!checkFile.exists()) {
+ // If normal file doens't exist, check if .complete version does
+ checkFile = new File(entryFile.getParent(), FileUtil.getBaseName(entryFile.getName())
+ + ".complete." + FileUtil.getExtension(entryFile.getName()));
+ }
+
+ String entryName = getName(entryFile);
+ if(checkFile.exists() && entryName != null){
+ songCount++;
+ }
+ }
+
+ playlist.setSongCount(Integer.toString(songCount));
+ } catch(Exception e) {
+ Log.w(TAG, "Failed to count songs in playlist", e);
+ } finally {
+ Util.close(buffer);
+ Util.close(reader);
+ }
+
playlists.add(playlist);
}
}
@@ -684,10 +720,16 @@ public class OfflineMusicService implements MusicService {
for(File file: dir.listFiles()) {
BufferedReader br = new BufferedReader(new FileReader(file));
while ((line = br.readLine()) != null && !"".equals(line)) {
+ String[] parts = line.split("\t");
+
PodcastChannel channel = new PodcastChannel();
- channel.setId(line);
- channel.setName(line);
+ channel.setId(parts[0]);
+ channel.setName(parts[0]);
channel.setStatus("completed");
+
+ if(parts.length > 1) {
+ channel.setUrl(parts[1]);
+ }
if(FileUtil.getPodcastDirectory(context, channel).exists() && !channels.contains(channel)) {
channels.add(channel);
diff --git a/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java b/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java
index 459c8c9e..ed34e1cb 100644
--- a/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java
+++ b/app/src/main/java/github/daneren2005/dsub/service/RESTMusicService.java
@@ -1204,7 +1204,7 @@ public class RESTMusicService implements MusicService {
String content = "";
for(PodcastChannel channel: channels) {
- content += channel.getName() + "\n";
+ content += channel.getName() + "\t" + channel.getUrl() + "\n";
}
File file = FileUtil.getPodcastFile(context, Util.getServerName(context, getInstance(context)));
diff --git a/app/src/main/java/github/daneren2005/dsub/util/FileUtil.java b/app/src/main/java/github/daneren2005/dsub/util/FileUtil.java
index 990eae06..185a6b29 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/FileUtil.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/FileUtil.java
@@ -741,23 +741,28 @@ public class FileUtil {
return index == -1 ? name : name.substring(0, index);
}
- public static Pair<Long, Long> getUsedSize(Context context, File file) {
+ public static Long[] getUsedSize(Context context, File file) {
long number = 0L;
+ long permanent = 0L;
long size = 0L;
if(file.isFile()) {
if(isMediaFile(file)) {
- return new Pair<Long, Long>(1L, file.length());
+ if(file.getAbsolutePath().indexOf(".complete") == -1) {
+ permanent++;
+ }
+ return new Long[] {1L, permanent, file.length()};
} else {
- return new Pair<Long, Long>(0L, 0L);
+ return new Long[] {0L, 0L, 0L};
}
} else {
for (File child : FileUtil.listFiles(file)) {
- Pair<Long, Long> pair = getUsedSize(context, child);
- number += pair.getFirst();
- size += pair.getSecond();
+ Long[] pair = getUsedSize(context, child);
+ number += pair[0];
+ permanent += pair[1];
+ size += pair[2];
}
- return new Pair<Long, Long>(number, size);
+ return new Long[] {number, permanent, size};
}
}
diff --git a/app/src/main/java/github/daneren2005/dsub/util/Util.java b/app/src/main/java/github/daneren2005/dsub/util/Util.java
index ce26bf1e..db0cb7c1 100644
--- a/app/src/main/java/github/daneren2005/dsub/util/Util.java
+++ b/app/src/main/java/github/daneren2005/dsub/util/Util.java
@@ -19,6 +19,7 @@ package github.daneren2005.dsub.util;
import android.annotation.TargetApi;
import android.app.Activity;
+import android.support.annotation.StringRes;
import android.support.v7.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
@@ -45,11 +46,14 @@ import android.text.method.LinkMovementMethod;
import android.text.util.Linkify;
import android.util.Log;
import android.view.Gravity;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.activity.SettingsActivity;
import github.daneren2005.dsub.activity.SubsonicFragmentActivity;
+import github.daneren2005.dsub.adapter.DetailsAdapter;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.domain.PlayerState;
import github.daneren2005.dsub.domain.RepeatMode;
@@ -73,8 +77,10 @@ import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
+import java.util.List;
import java.util.Locale;
import java.util.TimeZone;
@@ -1137,6 +1143,32 @@ public final class Util {
((TextView)dialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());
}
+ public static void showDetailsDialog(Context context, @StringRes int title, List<Integer> headers, List<String> details) {
+ List<String> headerStrings = new ArrayList<>();
+ for(@StringRes Integer res: headers) {
+ headerStrings.add(context.getResources().getString(res));
+ }
+ showDetailsDialog(context, context.getResources().getString(title), headerStrings, details);
+ }
+ public static void showDetailsDialog(Context context, String title, List<String> headers, List<String> details) {
+ ListView listView = new ListView(context);
+ listView.setAdapter(new DetailsAdapter(context, R.layout.details_item, headers, details));
+ listView.setDivider(null);
+ listView.setScrollbarFadingEnabled(false);
+
+ new AlertDialog.Builder(context)
+ // .setIcon(android.R.drawable.ic_dialog_info)
+ .setTitle(title)
+ .setView(listView)
+ .setPositiveButton(R.string.common_close, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int i) {
+ dialog.dismiss();
+ }
+ })
+ .show();
+ }
+
public static void sleepQuietly(long millis) {
try {
Thread.sleep(millis);
diff --git a/app/src/main/res/layout/details_item.xml b/app/src/main/res/layout/details_item.xml
new file mode 100644
index 00000000..4ef5fef0
--- /dev/null
+++ b/app/src/main/res/layout/details_item.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="8dp">
+
+ <TextView
+ android:id="@+id/detail_name"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:textColor="?android:textColorPrimary"
+ android:paddingLeft="14dp"
+ android:layout_gravity="center_vertical"/>
+
+ <TextView
+ android:id="@+id/detail_value"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="?android:textColorSecondary"
+ android:paddingLeft="14dp"
+ android:layout_gravity="center_vertical"/>
+
+</LinearLayout> \ No newline at end of file
diff --git a/app/src/main/res/menu/select_album_context.xml b/app/src/main/res/menu/select_album_context.xml
index 5b2529e7..388fd1f5 100644
--- a/app/src/main/res/menu/select_album_context.xml
+++ b/app/src/main/res/menu/select_album_context.xml
@@ -1,48 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:compat="http://schemas.android.com/apk/res-auto">
-
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/album_menu_info"
android:title="@string/common.info"/>
- <item
- android:id="@+id/album_menu_play_now"
- android:title="@string/common.play_now"
- />
-
- <item
- android:id="@+id/album_menu_play_shuffled"
- android:title="@string/common.play_shuffled"
- />
-
- <group android:id="@+id/hide_play_next">
- <item
- android:id="@+id/album_menu_play_next"
- android:title="@string/common.play_next"/>
- </group>
-
- <group android:id="@+id/hide_play_last">
- <item
- android:id="@+id/album_menu_play_last"
- android:title="@string/common.play_last"/>
- </group>
-
- <item
- android:id="@+id/album_menu_download"
- android:title="@string/common.download"
- />
-
- <item
- android:id="@+id/album_menu_pin"
- android:title="@string/common.pin"
- />
-
- <item
- android:id="@+id/album_menu_delete"
- android:title="@string/menu.delete_cache"/>
-
<item
android:id="@+id/album_menu_show_artist"
android:title="@string/menu.show_artist"/>
diff --git a/app/src/main/res/menu/select_album_context_offline.xml b/app/src/main/res/menu/select_album_context_offline.xml
index a1805f5b..60858d91 100644
--- a/app/src/main/res/menu/select_album_context_offline.xml
+++ b/app/src/main/res/menu/select_album_context_offline.xml
@@ -1,31 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:compat="http://schemas.android.com/apk/res-auto">
- <item
- android:id="@+id/album_menu_play_now"
- android:title="@string/common.play_now"
- />
-
- <item
- android:id="@+id/album_menu_play_shuffled"
- android:title="@string/common.play_shuffled"
- />
-
- <group android:id="@+id/hide_play_next">
- <item
- android:id="@+id/album_menu_play_next"
- android:title="@string/common.play_next"/>
- </group>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
- <group android:id="@+id/hide_play_last">
- <item
- android:id="@+id/album_menu_play_last"
- android:title="@string/common.play_last"/>
- </group>
-
- <item
- android:id="@+id/album_menu_delete"
- android:title="@string/menu.delete_cache"/>
+ <item
+ android:id="@+id/album_menu_info"
+ android:title="@string/common.info"/>
<item
android:id="@+id/album_menu_star"
diff --git a/app/src/main/res/menu/select_artist_context.xml b/app/src/main/res/menu/select_artist_context.xml
index debc07c6..b8bce32d 100644
--- a/app/src/main/res/menu/select_artist_context.xml
+++ b/app/src/main/res/menu/select_artist_context.xml
@@ -1,43 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:compat="http://schemas.android.com/apk/res-auto">
-
- <item
- android:id="@+id/artist_menu_play_now"
- android:title="@string/common.play_now"
- />
-
- <item
- android:id="@+id/artist_menu_play_shuffled"
- android:title="@string/common.play_shuffled"
- />
-
- <group android:id="@+id/hide_play_next">
- <item
- android:id="@+id/artist_menu_play_next"
- android:title="@string/common.play_next"/>
- </group>
-
- <group android:id="@+id/hide_play_last">
- <item
- android:id="@+id/artist_menu_play_last"
- android:title="@string/common.play_last"/>
- </group>
-
- <item
- android:id="@+id/artist_menu_download"
- android:title="@string/common.download"
- />
-
- <item
- android:id="@+id/artist_menu_pin"
- android:title="@string/common.pin"
- />
-
- <item
- android:id="@+id/artist_menu_delete"
- android:title="@string/menu.delete_cache"/>
-
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:id="@+id/server_1_10">
<group android:id="@+id/hide_star">
<item
diff --git a/app/src/main/res/menu/select_artist_context_offline.xml b/app/src/main/res/menu/select_artist_context_offline.xml
deleted file mode 100644
index 17ee97e0..00000000
--- a/app/src/main/res/menu/select_artist_context_offline.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:compat="http://schemas.android.com/apk/res-auto">
-
- <item
- android:id="@+id/artist_menu_play_now"
- android:title="@string/common.play_now"
- />
-
- <item
- android:id="@+id/artist_menu_play_shuffled"
- android:title="@string/common.play_shuffled"
- />
-
- <group android:id="@+id/hide_play_next">
- <item
- android:id="@+id/artist_menu_play_next"
- android:title="@string/common.play_next"/>
- </group>
-
- <group android:id="@+id/hide_play_last">
- <item
- android:id="@+id/artist_menu_play_last"
- android:title="@string/common.play_last"/>
- </group>
-
- <item
- android:id="@+id/artist_menu_delete"
- android:title="@string/menu.delete_cache"/>
-</menu>
diff --git a/app/src/main/res/menu/select_bookmark_context.xml b/app/src/main/res/menu/select_bookmark_context.xml
index 2b1b83fd..d52db105 100644
--- a/app/src/main/res/menu/select_bookmark_context.xml
+++ b/app/src/main/res/menu/select_bookmark_context.xml
@@ -15,18 +15,6 @@
android:title="@string/menu.show_artist"/>
<item
- android:id="@+id/song_menu_download"
- android:title="@string/common.download"/>
-
- <item
- android:id="@+id/song_menu_pin"
- android:title="@string/common.pin"/>
-
- <item
- android:id="@+id/song_menu_delete"
- android:title="@string/menu.delete_cache"/>
-
- <item
android:id="@+id/bookmark_menu_delete"
android:title="@string/bookmark.delete"/>
</menu>
diff --git a/app/src/main/res/menu/select_playlist_context.xml b/app/src/main/res/menu/select_playlist_context.xml
index 47033d9c..4941e94b 100644
--- a/app/src/main/res/menu/select_playlist_context.xml
+++ b/app/src/main/res/menu/select_playlist_context.xml
@@ -7,21 +7,6 @@
android:title="@string/common.info"
/>
- <item
- android:id="@+id/playlist_menu_play_now"
- android:title="@string/common.play_now"
- />
-
- <item
- android:id="@+id/playlist_menu_play_shuffled"
- android:title="@string/common.play_shuffled"
- />
-
- <item
- android:id="@+id/playlist_menu_download"
- android:title="@string/common.download"
- />
-
<item
android:id="@+id/playlist_menu_sync"
android:title="@string/menu.keep_synced"/>
diff --git a/app/src/main/res/menu/select_playlist_context_offline.xml b/app/src/main/res/menu/select_playlist_context_offline.xml
index d63aec17..6745d850 100644
--- a/app/src/main/res/menu/select_playlist_context_offline.xml
+++ b/app/src/main/res/menu/select_playlist_context_offline.xml
@@ -1,13 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
-<menu xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:compat="http://schemas.android.com/apk/res-auto">
- <item
- android:id="@+id/playlist_menu_play_now"
- android:title="@string/common.play_now"
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item
+ android:id="@+id/playlist_info"
+ android:title="@string/common.info"
/>
-
- <item
- android:id="@+id/playlist_menu_play_shuffled"
- android:title="@string/common.play_shuffled"
- />
</menu> \ No newline at end of file
diff --git a/app/src/main/res/menu/select_podcast_episode_context.xml b/app/src/main/res/menu/select_podcast_episode_context.xml
index bacccda3..31f2a051 100644
--- a/app/src/main/res/menu/select_podcast_episode_context.xml
+++ b/app/src/main/res/menu/select_podcast_episode_context.xml
@@ -7,7 +7,7 @@
android:title="@string/common.info"
/>
- <item
+ <item
android:id="@+id/song_menu_play_now"
android:title="@string/common.play_now"
/>
@@ -23,16 +23,16 @@
android:id="@+id/song_menu_play_last"
android:title="@string/common.play_last"/>
</group>
-
- <item
+
+ <item
android:id="@+id/song_menu_download"
android:title="@string/common.download"
/>
-
- <item
+
+ <item
android:id="@+id/song_menu_delete"
android:title="@string/menu.delete_cache"/>
-
+
<group android:id="@+id/server_1.9">
<item
android:id="@+id/bookmark_menu_delete"
diff --git a/app/src/main/res/menu/select_podcast_episode_context_offline.xml b/app/src/main/res/menu/select_podcast_episode_context_offline.xml
index 587d01f7..301746f4 100644
--- a/app/src/main/res/menu/select_podcast_episode_context_offline.xml
+++ b/app/src/main/res/menu/select_podcast_episode_context_offline.xml
@@ -6,8 +6,8 @@
android:id="@+id/song_menu_info"
android:title="@string/common.info"
/>
-
- <item
+
+ <item
android:id="@+id/song_menu_play_now"
android:title="@string/common.play_now"
/>
@@ -23,8 +23,8 @@
android:id="@+id/song_menu_play_last"
android:title="@string/common.play_last"/>
</group>
-
- <item
+
+ <item
android:id="@+id/song_menu_delete"
android:title="@string/menu.delete_cache"/>
</menu>
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index cd387b65..d4a239a6 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -42,13 +42,7 @@
<string name="main.welcome_text">Willkommen zu DSub! Die App ist aktuell für den Subsonic-Demo-Server konfiguriert. Nachdem Sie Ihren eigenen Server
aufgesetzt haben (verfügbar unter <b>subsonic.org</b>) könne Sie diesen unter <b>Einstellungen</b> konfigurieren.</string>
<string name="main.about_title">Über DSub</string>
- <string name="main.about_text">Autor: Scott Jackson
- \nEmail: dsub.android@gmail.com
- \nVersion: %1$s
- \nLokal gespeicherte Titel: %2$s
- \nGenutzter Speicher: %3$s von %4$s
- \nVerfügbarer Speicher: %5$s von %6$s</string>
- <string name="main.faq_title">FAQ</string>
+ <string name="main.faq_title">FAQ</string>
<string name="main.faq_text">
<![CDATA[
<font color="red">Cache vs Permanenter Cache</font>:
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 3c2593e2..e4d80211 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -41,13 +41,7 @@
<string name="main.welcome_title">Bienvenido!</string>
<string name="main.welcome_text">Bienvenido a DSub! Ahora la aplicación está configurada para usar el servidor de demostración de Subsonic. Cuando configures tu servidor personal (disponible en <b>subsonic.org</b>), accede a <b>Preferencias</b> y cambia la configuración para conectarte.</string>
<string name="main.about_title">Acerca de DSub</string>
- <string name="main.about_text">Autor: Scott Jackson
- \nEmail: dsub.android@gmail.com
- \nVersión: %1$s
- \nArchivos en caché: %2$s
- \nEspacio usado: %3$s of %4$s
- \nEspacio disponible: %5$s of %6$s</string>
- <string name="main.select_server">Seleccionar servidor</string>
+ <string name="main.select_server">Seleccionar servidor</string>
<string name="main.shuffle">Reproducción aleatoria</string>
<string name="main.offline">Modo Offline</string>
<string name="main.online">Modo Online</string>
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index cea3c77d..84e3dd75 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -41,12 +41,6 @@
<string name="main.welcome_title">Bienvenue !</string>
<string name="main.welcome_text">Bienvenue dans DSub ! L\'application est actuellement configurée pour se connecter au serveur de démo Subsonic (<b>demo.subsonic.org</b>). Vous pouvez configurer votre propre serveur dans les paramètres. Choisir <b>Paramètres</b> et mettre à jour la configuration pour vous y connecter.</string>
<string name="main.about_title">A propos de DSub</string>
- <string name="main.about_text">Auteur : Scott Jackson
- \nEmail : dsub.android@gmail.com
- \nVersion : %1$s
- \nFichiers en cache : %2$s
- \nEspace utilisé : %3$s de %4$s
- \nEspace dispo. : %5$s de %6$s</string>
<string name="main.faq_title">FAQ</string>
<string name="main.faq_text">
<![CDATA[
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 816e605a..481a4c99 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -42,12 +42,6 @@
<string name="main.welcome_text">Üdvözli a DSub! Az alkalmazás még nincs beállítva. Miután konfigurálta saját kiszolgálóját
(elérhető: <b>subsonic.org</b>), húzza balról jobbra az oldalsávot, lépjen be a <b>Beállítások</b> menüpontba és adja meg a kapcsolódási adatokat!</string>
<string name="main.about_title">DSub információk</string>
- <string name="main.about_text">Fejlesztő: Scott Jackson
- \nEmail: dsub.android@gmail.com
- \nVerzió: %1$s
- \nGyorsítótárazott fájlok: %2$s
- \nFelhasznált tároló: %3$s/%4$s
- \nFelhasználható tároló: %5$s/%6$s</string>
<string name="main.faq_title">GYIK</string>
<string name="main.faq_text">
<![CDATA[
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 0f904d95..15c79a69 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -32,12 +32,6 @@
<string name="main.welcome_text">Добро пожаловать в DSub! Это приложение настроено на работу с демо сервером Subsonic. После настройки Вашего персонального сервера (доступен на <b>subsonic.org</b>), пожалуйста, перейдите в <b>Настройки</b> и измените параметры для подключения.</string>
<string name="main.about_title">О программе DSub</string>
- <string name="main.about_text">Автор: Scott Jackson
- \nEmail: dsub.android@gmail.com
- \nВерсия: %1$s
- \nFiles Cached: %2$s
- \nИспользовано места: %3$s из %4$s
- \nДоступно места: %5$s из %6$s</string>
<string name="main.select_server">Выбрать сервер</string>
<string name="main.shuffle">Случайное воспроизведение</string>
<string name="main.offline">Отключиться</string>
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index f7c91da3..74d69e5e 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -25,6 +25,7 @@
<string name="common.confirm_message_cache">cache</string>
<string name="common.empty">No data</string>
<string name="common.warning">Warning</string>
+ <string name="common.close">Close</string>
<string name="button_bar.home">Home</string>
<string name="button_bar.browse">Library</string>
@@ -42,12 +43,6 @@
<string name="main.welcome_text">Welcome to DSub! The app is currently configured to use the Subsonic demo server. After you\'ve
set up your personal server (available from <b>subsonic.org</b>), please go to <b>Settings</b> and change the configuration to connect to it.</string>
<string name="main.about_title">About DSub</string>
- <string name="main.about_text">Author: Scott Jackson
- \nEmail: dsub.android@gmail.com
- \nVersion: %1$s
- \nFiles Cached: %2$s
- \nUsed Space: %3$s of %4$s
- \nAvailable Space: %5$s of %6$s</string>
<string name="main.faq_title">FAQ</string>
<string name="main.faq_text">
<![CDATA[
@@ -589,6 +584,43 @@
<string name="tasker.edit_server_offline">Toggle offline: </string>
<string name="tasker.edit_do_nothing">Do Nothing</string>
+ <string name="details.title.song">Song Details</string>
+ <string name="details.title.album">Album Details</string>
+ <string name="details.title.podcast">Podcast Details</string>
+ <string name="details.title.playlist">Playlist Details</string>
+ <string name="details.podcast">Podcast</string>
+ <string name="details.status">Status</string>
+ <string name="details.artist">Artist</string>
+ <string name="details.album">Album</string>
+ <string name="details.track">Track</string>
+ <string name="details.genre">Genre</string>
+ <string name="details.year">Year</string>
+ <string name="details.server_format">Server Format</string>
+ <string name="details.server_bitrate">Server Bitrate</string>
+ <string name="details.cached_format">Cached Format</string>
+ <string name="details.cached_bitrate">Cached Bitrate</string>
+ <string name="details.size">Size</string>
+ <string name="details.length">Length</string>
+ <string name="details.bookmark_position">Bookmark Position</string>
+ <string name="details.rating">Rating</string>
+ <string name="details.description">Description</string>
+ <string name="details.owner">Owner</string>
+ <string name="details.comments">Comments</string>
+ <string name="details.song_count">Song Count</string>
+ <string name="details.public">Public</string>
+ <string name="details.created">Created</string>
+ <string name="details.title">Title</string>
+ <string name="details.url">URL</string>
+ <string name="details.error">Error Message</string>
+ <string name="details.author">Author</string>
+ <string name="details.email">Email</string>
+ <string name="details.version">Version</string>
+ <string name="details.files_cached">Files Cached</string>
+ <string name="details.files_permanent">Permanent Cached</string>
+ <string name="details.used_space">Used Space</string>
+ <string name="details.available_space">Available Space</string>
+ <string name="details.of">%1$s of %2$s</string>
+
<plurals name="select_album_n_songs">
<item quantity="zero">No songs</item>
<item quantity="one">One song</item>