mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-04-24 12:50:58 +03:00
Minor fixes
Cleaned up TODOs Cleaned up code
This commit is contained in:
parent
d70d2cc2fb
commit
86bfcefe93
ultrasonic/src/main
java/org/moire/ultrasonic
fragment
AboutFragment.javaBookmarksFragment.javaChatFragment.javaLyricsFragment.javaMainFragment.javaNowPlayingFragment.javaPlayerFragment.javaPlaylistsFragment.javaPodcastFragment.javaSearchFragment.javaSelectAlbumFragment.javaSelectGenreFragment.javaSharesFragment.java
service
CachedMusicService.javaDownloadFile.javaJukeboxMediaPlayer.javaMediaPlayerControllerImpl.javaMediaPlayerService.javaMusicService.javaOfflineMusicService.javaScrobbler.java
util
view
kotlin/org/moire/ultrasonic
activity
di
fragment
ArtistListModel.ktEditServerFragment.ktFragmentTitle.ktSelectArtistFragment.ktServerSelectorFragment.kt
service
subsonic
util
CancellationToken.ktNowPlayingEventDistributor.ktNowPlayingEventListener.ktSubsonicUncaughtExceptionHandler.ktThemeChangedEventDistributor.ktThemeChangedEventListener.kt
view
res/layout
@ -19,8 +19,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
public class AboutFragment extends Fragment {
|
||||
|
||||
private WebView webView;
|
||||
|
@ -27,7 +27,7 @@ import org.moire.ultrasonic.subsonic.VideoPlayer;
|
||||
import org.moire.ultrasonic.util.CancellationToken;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.Pair;
|
||||
import org.moire.ultrasonic.util.TabActivityBackgroundTask;
|
||||
import org.moire.ultrasonic.util.FragmentBackgroundTask;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
import org.moire.ultrasonic.view.EntryAdapter;
|
||||
|
||||
@ -35,7 +35,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import kotlin.Lazy;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static org.koin.java.KoinJavaComponent.inject;
|
||||
|
||||
@ -73,6 +72,7 @@ public class BookmarksFragment extends Fragment {
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
cancellationToken = new CancellationToken();
|
||||
albumButtons = view.findViewById(R.id.menu_album);
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
refreshAlbumListView = view.findViewById(R.id.select_album_entries_refresh);
|
||||
albumListView = view.findViewById(R.id.select_album_entries_list);
|
||||
@ -186,7 +186,6 @@ public class BookmarksFragment extends Fragment {
|
||||
FragmentTitle.Companion.setTitle(this, R.string.button_bar_bookmarks);
|
||||
|
||||
enableButtons();
|
||||
|
||||
getBookmarks();
|
||||
}
|
||||
|
||||
@ -203,7 +202,7 @@ public class BookmarksFragment extends Fragment {
|
||||
@Override
|
||||
protected MusicDirectory load(MusicService service) throws Exception
|
||||
{
|
||||
return Util.getSongsFromBookmarks(service.getBookmarks(getContext(), this));
|
||||
return Util.getSongsFromBookmarks(service.getBookmarks(getContext()));
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
@ -239,27 +238,8 @@ public class BookmarksFragment extends Fragment {
|
||||
|
||||
private void refresh()
|
||||
{
|
||||
// TODO: create better restart
|
||||
getView().post(new Runnable() {
|
||||
public void run() {
|
||||
Timber.d("Refresh called...");
|
||||
if (getArguments() == null) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
setArguments(bundle);
|
||||
} else {
|
||||
getArguments().putBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
}
|
||||
onViewCreated(getView(), null);
|
||||
}
|
||||
});
|
||||
|
||||
/* finish();
|
||||
Intent intent = getIntent();
|
||||
intent.putExtra(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
startActivityForResultWithoutTransition(this, intent);
|
||||
|
||||
*/
|
||||
enableButtons();
|
||||
getBookmarks();
|
||||
}
|
||||
|
||||
private void selectAllOrNone()
|
||||
@ -392,7 +372,7 @@ public class BookmarksFragment extends Fragment {
|
||||
mediaPlayerController.getValue().unpin(songs);
|
||||
}
|
||||
|
||||
private abstract class LoadTask extends TabActivityBackgroundTask<Pair<MusicDirectory, Boolean>>
|
||||
private abstract class LoadTask extends FragmentBackgroundTask<Pair<MusicDirectory, Boolean>>
|
||||
{
|
||||
public LoadTask()
|
||||
{
|
||||
@ -406,7 +386,7 @@ public class BookmarksFragment extends Fragment {
|
||||
{
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
MusicDirectory dir = load(musicService);
|
||||
boolean valid = musicService.isLicenseValid(getContext(), this);
|
||||
boolean valid = musicService.isLicenseValid(getContext());
|
||||
return new Pair<>(dir, valid);
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@ import android.widget.TextView;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
||||
@ -29,7 +30,7 @@ import org.moire.ultrasonic.service.MusicService;
|
||||
import org.moire.ultrasonic.service.MusicServiceFactory;
|
||||
import org.moire.ultrasonic.util.BackgroundTask;
|
||||
import org.moire.ultrasonic.util.CancellationToken;
|
||||
import org.moire.ultrasonic.util.TabActivityBackgroundTask;
|
||||
import org.moire.ultrasonic.util.FragmentBackgroundTask;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
import org.moire.ultrasonic.view.ChatAdapter;
|
||||
|
||||
@ -52,6 +53,7 @@ public class ChatFragment extends Fragment {
|
||||
private volatile static Long lastChatMessageTime = (long) 0;
|
||||
private static final ArrayList<ChatMessage> messageList = new ArrayList<ChatMessage>();
|
||||
private CancellationToken cancellationToken;
|
||||
private SwipeRefreshLayout swipeRefresh;
|
||||
|
||||
private final Lazy<ActiveServerProvider> activeServerProvider = inject(ActiveServerProvider.class);
|
||||
|
||||
@ -70,6 +72,9 @@ public class ChatFragment extends Fragment {
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
swipeRefresh = view.findViewById(R.id.chat_refresh);
|
||||
swipeRefresh.setEnabled(false);
|
||||
|
||||
cancellationToken = new CancellationToken();
|
||||
messageEditText = view.findViewById(R.id.chat_edittext);
|
||||
sendButton = view.findViewById(R.id.chat_send);
|
||||
@ -238,13 +243,13 @@ public class ChatFragment extends Fragment {
|
||||
{
|
||||
messageEditText.setText("");
|
||||
|
||||
BackgroundTask<Void> task = new TabActivityBackgroundTask<Void>(getActivity(), false, null, cancellationToken)
|
||||
BackgroundTask<Void> task = new FragmentBackgroundTask<Void>(getActivity(), false, swipeRefresh, cancellationToken)
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground() throws Throwable
|
||||
{
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
musicService.addChatMessage(message, getContext(), this);
|
||||
musicService.addChatMessage(message, getContext());
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -262,14 +267,13 @@ public class ChatFragment extends Fragment {
|
||||
|
||||
private synchronized void load()
|
||||
{
|
||||
// TODO: Do we need a SwipeToRefresh progress indicator?
|
||||
BackgroundTask<List<ChatMessage>> task = new TabActivityBackgroundTask<List<ChatMessage>>(getActivity(), false, null, cancellationToken)
|
||||
BackgroundTask<List<ChatMessage>> task = new FragmentBackgroundTask<List<ChatMessage>>(getActivity(), false, swipeRefresh, cancellationToken)
|
||||
{
|
||||
@Override
|
||||
protected List<ChatMessage> doInBackground() throws Throwable
|
||||
{
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
return musicService.getChatMessages(lastChatMessageTime, getContext(), this);
|
||||
return musicService.getChatMessages(lastChatMessageTime, getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -18,7 +18,7 @@ import org.moire.ultrasonic.service.MusicServiceFactory;
|
||||
import org.moire.ultrasonic.util.BackgroundTask;
|
||||
import org.moire.ultrasonic.util.CancellationToken;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.TabActivityBackgroundTask;
|
||||
import org.moire.ultrasonic.util.FragmentBackgroundTask;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
|
||||
import timber.log.Timber;
|
||||
@ -66,15 +66,17 @@ public class LyricsFragment extends Fragment {
|
||||
|
||||
private void load()
|
||||
{
|
||||
BackgroundTask<Lyrics> task = new TabActivityBackgroundTask<Lyrics>(getActivity(), true, swipe, cancellationToken)
|
||||
BackgroundTask<Lyrics> task = new FragmentBackgroundTask<Lyrics>(getActivity(), true, swipe, cancellationToken)
|
||||
{
|
||||
@Override
|
||||
protected Lyrics doInBackground() throws Throwable
|
||||
{
|
||||
String artist = getArguments().getString(Constants.INTENT_EXTRA_NAME_ARTIST);
|
||||
String title = getArguments().getString(Constants.INTENT_EXTRA_NAME_TITLE);
|
||||
Bundle arguments = getArguments();
|
||||
if (arguments == null) return null;
|
||||
String artist = arguments.getString(Constants.INTENT_EXTRA_NAME_ARTIST);
|
||||
String title = arguments.getString(Constants.INTENT_EXTRA_NAME_TITLE);
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
return musicService.getLyrics(artist, title, getContext(), this);
|
||||
return musicService.getLyrics(artist, title, getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.moire.ultrasonic.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -134,7 +134,7 @@ public class NowPlayingFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Check if this empty onClickListener is necessary
|
||||
// This empty onClickListener is necessary for the onTouchListener to work
|
||||
getView().setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
@ -115,7 +115,6 @@ public class PlayerFragment extends Fragment implements GestureDetector.OnGestur
|
||||
private SilentBackgroundTask<Void> onProgressChangedTask;
|
||||
LinearLayout visualizerViewLayout;
|
||||
private MenuItem starMenuItem;
|
||||
private LinearLayout ratingLinearLayout;
|
||||
private ImageView fiveStar1ImageView;
|
||||
private ImageView fiveStar2ImageView;
|
||||
private ImageView fiveStar3ImageView;
|
||||
@ -188,7 +187,7 @@ public class PlayerFragment extends Fragment implements GestureDetector.OnGestur
|
||||
|
||||
visualizerViewLayout = view.findViewById(R.id.download_visualizer_view_layout);
|
||||
|
||||
ratingLinearLayout = view.findViewById(R.id.song_rating);
|
||||
LinearLayout ratingLinearLayout = view.findViewById(R.id.song_rating);
|
||||
fiveStar1ImageView = view.findViewById(R.id.song_five_star_1);
|
||||
fiveStar2ImageView = view.findViewById(R.id.song_five_star_2);
|
||||
fiveStar3ImageView = view.findViewById(R.id.song_five_star_3);
|
||||
@ -197,7 +196,7 @@ public class PlayerFragment extends Fragment implements GestureDetector.OnGestur
|
||||
|
||||
if (!useFiveStarRating) ratingLinearLayout.setVisibility(View.GONE);
|
||||
|
||||
hollowStar = Util.getDrawableFromAttribute(getContext(), R.attr.star_hollow);
|
||||
hollowStar = Util.getDrawableFromAttribute(view.getContext(), R.attr.star_hollow);
|
||||
fullStar = Util.getDrawableFromAttribute(getContext(), R.attr.star_full);
|
||||
|
||||
fiveStar1ImageView.setOnClickListener(new View.OnClickListener()
|
||||
@ -893,250 +892,207 @@ public class PlayerFragment extends Fragment implements GestureDetector.OnGestur
|
||||
entry = song.getSong();
|
||||
}
|
||||
|
||||
switch (menuItemId)
|
||||
{
|
||||
case R.id.menu_show_artist:
|
||||
if (entry == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Util.getShouldUseId3Tags(getContext()))
|
||||
{
|
||||
bundle = new Bundle();
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getArtistId());
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getArtist());
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_PARENT_ID, entry.getArtistId());
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true);
|
||||
Navigation.findNavController(getView()).navigate(R.id.playerToSelectAlbum, bundle);
|
||||
}
|
||||
|
||||
return true;
|
||||
case R.id.menu_show_album:
|
||||
if (entry == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
String albumId = Util.getShouldUseId3Tags(getContext()) ? entry.getAlbumId() : entry.getParent();
|
||||
bundle = new Bundle();
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ID, albumId);
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getAlbum());
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_PARENT_ID, entry.getParent());
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_IS_ALBUM, true);
|
||||
Navigation.findNavController(getView()).navigate(R.id.playerToSelectAlbum, bundle);
|
||||
return true;
|
||||
case R.id.menu_lyrics:
|
||||
if (entry == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bundle = new Bundle();
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ARTIST, entry.getArtist());
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_TITLE, entry.getTitle());
|
||||
Navigation.findNavController(getView()).navigate(R.id.playerToLyrics, bundle);
|
||||
return true;
|
||||
case R.id.menu_remove:
|
||||
mediaPlayerControllerLazy.getValue().remove(song);
|
||||
onDownloadListChanged();
|
||||
return true;
|
||||
case R.id.menu_item_screen_on_off:
|
||||
if (mediaPlayerControllerLazy.getValue().getKeepScreenOn())
|
||||
{
|
||||
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
mediaPlayerControllerLazy.getValue().setKeepScreenOn(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
mediaPlayerControllerLazy.getValue().setKeepScreenOn(true);
|
||||
}
|
||||
return true;
|
||||
case R.id.menu_shuffle:
|
||||
mediaPlayerControllerLazy.getValue().shuffle();
|
||||
Util.toast(getContext(), R.string.download_menu_shuffle_notification);
|
||||
return true;
|
||||
case R.id.menu_item_equalizer:
|
||||
Navigation.findNavController(getView()).navigate(R.id.playerToEqualizer);
|
||||
return true;
|
||||
case R.id.menu_item_visualizer:
|
||||
final boolean active = !visualizerView.isActive();
|
||||
visualizerView.setActive(active);
|
||||
|
||||
if (!visualizerView.isActive())
|
||||
{
|
||||
visualizerViewLayout.setVisibility(View.GONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
visualizerViewLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
mediaPlayerControllerLazy.getValue().setShowVisualization(visualizerView.isActive());
|
||||
Util.toast(getContext(), active ? R.string.download_visualizer_on : R.string.download_visualizer_off);
|
||||
return true;
|
||||
case R.id.menu_item_jukebox:
|
||||
final boolean jukeboxEnabled = !mediaPlayerControllerLazy.getValue().isJukeboxEnabled();
|
||||
mediaPlayerControllerLazy.getValue().setJukeboxEnabled(jukeboxEnabled);
|
||||
Util.toast(getContext(), jukeboxEnabled ? R.string.download_jukebox_on : R.string.download_jukebox_off, false);
|
||||
return true;
|
||||
case R.id.menu_item_toggle_list:
|
||||
toggleFullScreenAlbumArt();
|
||||
return true;
|
||||
case R.id.menu_item_clear_playlist:
|
||||
mediaPlayerControllerLazy.getValue().setShufflePlayEnabled(false);
|
||||
mediaPlayerControllerLazy.getValue().clear();
|
||||
onDownloadListChanged();
|
||||
return true;
|
||||
case R.id.menu_item_save_playlist:
|
||||
if (mediaPlayerControllerLazy.getValue().getPlaylistSize() > 0)
|
||||
{
|
||||
showSavePlaylistDialog();
|
||||
}
|
||||
return true;
|
||||
case R.id.menu_item_star:
|
||||
if (currentSong == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
final boolean isStarred = currentSong.getStarred();
|
||||
final String id = currentSong.getId();
|
||||
|
||||
if (isStarred)
|
||||
{
|
||||
starMenuItem.setIcon(hollowStar);
|
||||
currentSong.setStarred(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
starMenuItem.setIcon(fullStar);
|
||||
currentSong.setStarred(true);
|
||||
}
|
||||
|
||||
new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
final MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
|
||||
try
|
||||
{
|
||||
if (isStarred)
|
||||
{
|
||||
musicService.unstar(id, null, null, getContext(), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
musicService.star(id, null, null, getContext(), null);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Timber.e(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
return true;
|
||||
case R.id.menu_item_bookmark_set:
|
||||
if (currentSong == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
final String songId = currentSong.getId();
|
||||
final int playerPosition = mediaPlayerControllerLazy.getValue().getPlayerPosition();
|
||||
|
||||
currentSong.setBookmarkPosition(playerPosition);
|
||||
|
||||
String bookmarkTime = Util.formatTotalDuration(playerPosition, true);
|
||||
|
||||
new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
final MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
|
||||
try
|
||||
{
|
||||
musicService.createBookmark(songId, playerPosition, getContext(), null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Timber.e(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
String msg = getResources().getString(R.string.download_bookmark_set_at_position, bookmarkTime);
|
||||
|
||||
Util.toast(getContext(), msg);
|
||||
|
||||
return true;
|
||||
case R.id.menu_item_bookmark_delete:
|
||||
if (currentSong == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
final String bookmarkSongId = currentSong.getId();
|
||||
currentSong.setBookmarkPosition(0);
|
||||
|
||||
new Thread(new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
final MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
|
||||
try
|
||||
{
|
||||
musicService.deleteBookmark(bookmarkSongId, getContext(), null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Timber.e(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
Util.toast(getContext(), R.string.download_bookmark_removed);
|
||||
|
||||
return true;
|
||||
case R.id.menu_item_share:
|
||||
MediaPlayerController mediaPlayerController = mediaPlayerControllerLazy.getValue();
|
||||
List<MusicDirectory.Entry> entries = new ArrayList<>();
|
||||
|
||||
if (mediaPlayerController != null)
|
||||
{
|
||||
List<DownloadFile> downloadServiceSongs = mediaPlayerController.getPlayList();
|
||||
|
||||
if (downloadServiceSongs != null)
|
||||
{
|
||||
for (DownloadFile downloadFile : downloadServiceSongs)
|
||||
{
|
||||
if (downloadFile != null)
|
||||
{
|
||||
MusicDirectory.Entry playlistEntry = downloadFile.getSong();
|
||||
|
||||
if (playlistEntry != null)
|
||||
{
|
||||
entries.add(playlistEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shareHandler.getValue().createShare(this, entries, null, cancellationToken);
|
||||
return true;
|
||||
default:
|
||||
if (menuItemId == R.id.menu_show_artist) {
|
||||
if (entry == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Util.getShouldUseId3Tags(getContext())) {
|
||||
bundle = new Bundle();
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getArtistId());
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getArtist());
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_PARENT_ID, entry.getArtistId());
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true);
|
||||
Navigation.findNavController(getView()).navigate(R.id.playerToSelectAlbum, bundle);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_show_album) {
|
||||
if (entry == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String albumId = Util.getShouldUseId3Tags(getContext()) ? entry.getAlbumId() : entry.getParent();
|
||||
bundle = new Bundle();
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ID, albumId);
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getAlbum());
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_PARENT_ID, entry.getParent());
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_IS_ALBUM, true);
|
||||
Navigation.findNavController(getView()).navigate(R.id.playerToSelectAlbum, bundle);
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_lyrics) {
|
||||
if (entry == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bundle = new Bundle();
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_ARTIST, entry.getArtist());
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_TITLE, entry.getTitle());
|
||||
Navigation.findNavController(getView()).navigate(R.id.playerToLyrics, bundle);
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_remove) {
|
||||
mediaPlayerControllerLazy.getValue().remove(song);
|
||||
onDownloadListChanged();
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_screen_on_off) {
|
||||
if (mediaPlayerControllerLazy.getValue().getKeepScreenOn()) {
|
||||
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
mediaPlayerControllerLazy.getValue().setKeepScreenOn(false);
|
||||
} else {
|
||||
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||
mediaPlayerControllerLazy.getValue().setKeepScreenOn(true);
|
||||
}
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_shuffle) {
|
||||
mediaPlayerControllerLazy.getValue().shuffle();
|
||||
Util.toast(getContext(), R.string.download_menu_shuffle_notification);
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_equalizer) {
|
||||
Navigation.findNavController(getView()).navigate(R.id.playerToEqualizer);
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_visualizer) {
|
||||
final boolean active = !visualizerView.isActive();
|
||||
visualizerView.setActive(active);
|
||||
|
||||
if (!visualizerView.isActive()) {
|
||||
visualizerViewLayout.setVisibility(View.GONE);
|
||||
} else {
|
||||
visualizerViewLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
mediaPlayerControllerLazy.getValue().setShowVisualization(visualizerView.isActive());
|
||||
Util.toast(getContext(), active ? R.string.download_visualizer_on : R.string.download_visualizer_off);
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_jukebox) {
|
||||
final boolean jukeboxEnabled = !mediaPlayerControllerLazy.getValue().isJukeboxEnabled();
|
||||
mediaPlayerControllerLazy.getValue().setJukeboxEnabled(jukeboxEnabled);
|
||||
Util.toast(getContext(), jukeboxEnabled ? R.string.download_jukebox_on : R.string.download_jukebox_off, false);
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_toggle_list) {
|
||||
toggleFullScreenAlbumArt();
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_clear_playlist) {
|
||||
mediaPlayerControllerLazy.getValue().setShufflePlayEnabled(false);
|
||||
mediaPlayerControllerLazy.getValue().clear();
|
||||
onDownloadListChanged();
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_save_playlist) {
|
||||
if (mediaPlayerControllerLazy.getValue().getPlaylistSize() > 0) {
|
||||
showSavePlaylistDialog();
|
||||
}
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_star) {
|
||||
if (currentSong == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final boolean isStarred = currentSong.getStarred();
|
||||
final String id = currentSong.getId();
|
||||
|
||||
if (isStarred) {
|
||||
starMenuItem.setIcon(hollowStar);
|
||||
currentSong.setStarred(false);
|
||||
} else {
|
||||
starMenuItem.setIcon(fullStar);
|
||||
currentSong.setStarred(true);
|
||||
}
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
|
||||
try {
|
||||
if (isStarred) {
|
||||
musicService.unstar(id, null, null, getContext());
|
||||
} else {
|
||||
musicService.star(id, null, null, getContext());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Timber.e(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_bookmark_set) {
|
||||
if (currentSong == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final String songId = currentSong.getId();
|
||||
final int playerPosition = mediaPlayerControllerLazy.getValue().getPlayerPosition();
|
||||
|
||||
currentSong.setBookmarkPosition(playerPosition);
|
||||
|
||||
String bookmarkTime = Util.formatTotalDuration(playerPosition, true);
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
|
||||
try {
|
||||
musicService.createBookmark(songId, playerPosition, getContext());
|
||||
} catch (Exception e) {
|
||||
Timber.e(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
String msg = getResources().getString(R.string.download_bookmark_set_at_position, bookmarkTime);
|
||||
|
||||
Util.toast(getContext(), msg);
|
||||
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_bookmark_delete) {
|
||||
if (currentSong == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final String bookmarkSongId = currentSong.getId();
|
||||
currentSong.setBookmarkPosition(0);
|
||||
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
|
||||
try {
|
||||
musicService.deleteBookmark(bookmarkSongId, getContext());
|
||||
} catch (Exception e) {
|
||||
Timber.e(e);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
Util.toast(getContext(), R.string.download_bookmark_removed);
|
||||
|
||||
return true;
|
||||
} else if (menuItemId == R.id.menu_item_share) {
|
||||
MediaPlayerController mediaPlayerController = mediaPlayerControllerLazy.getValue();
|
||||
List<MusicDirectory.Entry> entries = new ArrayList<>();
|
||||
|
||||
if (mediaPlayerController != null) {
|
||||
List<DownloadFile> downloadServiceSongs = mediaPlayerController.getPlayList();
|
||||
|
||||
if (downloadServiceSongs != null) {
|
||||
for (DownloadFile downloadFile : downloadServiceSongs) {
|
||||
if (downloadFile != null) {
|
||||
MusicDirectory.Entry playlistEntry = downloadFile.getSong();
|
||||
|
||||
if (playlistEntry != null) {
|
||||
entries.add(playlistEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shareHandler.getValue().createShare(this, entries, null, cancellationToken);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void update(CancellationToken cancel)
|
||||
@ -1178,7 +1134,7 @@ public class PlayerFragment extends Fragment implements GestureDetector.OnGestur
|
||||
entries.add(downloadFile.getSong());
|
||||
}
|
||||
final MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
musicService.createPlaylist(null, playlistName, entries, getContext(), null);
|
||||
musicService.createPlaylist(null, playlistName, entries, getContext());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -41,14 +41,13 @@ import org.moire.ultrasonic.util.CacheCleaner;
|
||||
import org.moire.ultrasonic.util.CancellationToken;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.LoadingTask;
|
||||
import org.moire.ultrasonic.util.TabActivityBackgroundTask;
|
||||
import org.moire.ultrasonic.util.FragmentBackgroundTask;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
import org.moire.ultrasonic.view.PlaylistAdapter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import kotlin.Lazy;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static org.koin.java.KoinJavaComponent.inject;
|
||||
|
||||
@ -109,10 +108,9 @@ public class PlaylistsFragment extends Fragment {
|
||||
}
|
||||
});
|
||||
registerForContextMenu(playlistsListView);
|
||||
|
||||
FragmentTitle.Companion.setTitle(this, R.string.playlist_label);
|
||||
|
||||
load();
|
||||
load(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -123,38 +121,18 @@ public class PlaylistsFragment extends Fragment {
|
||||
|
||||
private void refresh()
|
||||
{
|
||||
// TODO: create better restart
|
||||
getView().post(new Runnable() {
|
||||
public void run() {
|
||||
Timber.d("Refresh called...");
|
||||
if (getArguments() == null) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
setArguments(bundle);
|
||||
} else {
|
||||
getArguments().putBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
}
|
||||
onViewCreated(getView(), null);
|
||||
}
|
||||
});
|
||||
|
||||
/* finish();
|
||||
Intent intent = new Intent(this, SelectPlaylistActivity.class);
|
||||
intent.putExtra(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
startActivityForResultWithoutTransition(this, intent);
|
||||
*/
|
||||
load(true);
|
||||
}
|
||||
|
||||
private void load()
|
||||
private void load(final boolean refresh)
|
||||
{
|
||||
BackgroundTask<List<Playlist>> task = new TabActivityBackgroundTask<List<Playlist>>(getActivity(), true, refreshPlaylistsListView, cancellationToken)
|
||||
BackgroundTask<List<Playlist>> task = new FragmentBackgroundTask<List<Playlist>>(getActivity(), true, refreshPlaylistsListView, cancellationToken)
|
||||
{
|
||||
@Override
|
||||
protected List<Playlist> doInBackground() throws Throwable
|
||||
{
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
boolean refresh = getArguments() != null && getArguments().getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, false);
|
||||
List<Playlist> playlists = musicService.getPlaylists(refresh, getContext(), this);
|
||||
List<Playlist> playlists = musicService.getPlaylists(refresh, getContext());
|
||||
|
||||
if (!ActiveServerProvider.Companion.isOffline(getContext()))
|
||||
new CacheCleaner(getContext()).cleanPlaylists(playlists);
|
||||
@ -258,7 +236,7 @@ public class PlaylistsFragment extends Fragment {
|
||||
protected Void doInBackground() throws Throwable
|
||||
{
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
musicService.deletePlaylist(playlist.getId(), getContext(), null);
|
||||
musicService.deletePlaylist(playlist.getId(), getContext());
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -348,7 +326,7 @@ public class PlaylistsFragment extends Fragment {
|
||||
String comment = commentBoxText != null ? commentBoxText.toString() : null;
|
||||
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
musicService.updatePlaylist(playlist.getId(), name, comment, publicBox.isChecked(), getContext(), null);
|
||||
musicService.updatePlaylist(playlist.getId(), name, comment, publicBox.isChecked(), getContext());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.moire.ultrasonic.fragment;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@ -11,6 +12,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.domain.PodcastsChannel;
|
||||
@ -19,7 +21,7 @@ import org.moire.ultrasonic.service.MusicServiceFactory;
|
||||
import org.moire.ultrasonic.util.BackgroundTask;
|
||||
import org.moire.ultrasonic.util.CancellationToken;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.TabActivityBackgroundTask;
|
||||
import org.moire.ultrasonic.util.FragmentBackgroundTask;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
import org.moire.ultrasonic.view.PodcastsChannelsAdapter;
|
||||
|
||||
@ -30,6 +32,7 @@ public class PodcastFragment extends Fragment {
|
||||
private View emptyTextView;
|
||||
ListView channelItemsListView = null;
|
||||
private CancellationToken cancellationToken;
|
||||
private SwipeRefreshLayout swipeRefresh;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
@ -47,6 +50,9 @@ public class PodcastFragment extends Fragment {
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
cancellationToken = new CancellationToken();
|
||||
swipeRefresh = view.findViewById(R.id.podcasts_refresh);
|
||||
swipeRefresh.setEnabled(false);
|
||||
|
||||
FragmentTitle.Companion.setTitle(this, R.string.podcasts_label);
|
||||
|
||||
emptyTextView = view.findViewById(R.id.select_podcasts_empty);
|
||||
@ -61,12 +67,11 @@ public class PodcastFragment extends Fragment {
|
||||
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_PODCAST_CHANNEL_ID, pc.getId());
|
||||
Navigation.findNavController(getView()).navigate(R.id.selectAlbumFragment, bundle);
|
||||
Navigation.findNavController(view).navigate(R.id.selectAlbumFragment, bundle);
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Probably a swipeRefresh should be added here in the long run
|
||||
load();
|
||||
load(view.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -75,26 +80,21 @@ public class PodcastFragment extends Fragment {
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
private void load()
|
||||
private void load(final Context context)
|
||||
{
|
||||
BackgroundTask<List<PodcastsChannel>> task = new TabActivityBackgroundTask<List<PodcastsChannel>>(getActivity(), true, null, cancellationToken)
|
||||
BackgroundTask<List<PodcastsChannel>> task = new FragmentBackgroundTask<List<PodcastsChannel>>(getActivity(), true, swipeRefresh, cancellationToken)
|
||||
{
|
||||
@Override
|
||||
protected List<PodcastsChannel> doInBackground() throws Throwable
|
||||
{
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
return musicService.getPodcastsChannels(false, getContext(), this);
|
||||
|
||||
/* TODO Why is here a cache cleaning? (original TODO text: c'est quoi ce nettoyage de cache ?)
|
||||
if (!Util.isOffline(PodcastsActivity.this))
|
||||
new CacheCleaner(PodcastsActivity.this, getDownloadService()).cleanPlaylists(playlists);
|
||||
*/
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(context);
|
||||
return musicService.getPodcastsChannels(false, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done(List<PodcastsChannel> result)
|
||||
{
|
||||
channelItemsListView.setAdapter(new PodcastsChannelsAdapter(getContext(), result));
|
||||
channelItemsListView.setAdapter(new PodcastsChannelsAdapter(context, result));
|
||||
emptyTextView.setVisibility(result.isEmpty() ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
};
|
||||
|
@ -24,6 +24,7 @@ import androidx.fragment.app.Fragment;
|
||||
import androidx.navigation.Navigation;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
||||
import org.moire.ultrasonic.domain.Artist;
|
||||
@ -42,7 +43,7 @@ import org.moire.ultrasonic.util.BackgroundTask;
|
||||
import org.moire.ultrasonic.util.CancellationToken;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.MergeAdapter;
|
||||
import org.moire.ultrasonic.util.TabActivityBackgroundTask;
|
||||
import org.moire.ultrasonic.util.FragmentBackgroundTask;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
import org.moire.ultrasonic.view.ArtistAdapter;
|
||||
import org.moire.ultrasonic.view.EntryAdapter;
|
||||
@ -128,7 +129,7 @@ public class SearchFragment extends Fragment {
|
||||
|
||||
list = view.findViewById(R.id.search_list);
|
||||
searchRefresh = view.findViewById(R.id.search_entries_refresh);
|
||||
searchRefresh.setEnabled(false); // TODO: Should this be enabled?
|
||||
searchRefresh.setEnabled(false); // TODO: It should be enabled if it is a good feature to refresh search results
|
||||
|
||||
list.setOnItemClickListener(new AdapterView.OnItemClickListener()
|
||||
{
|
||||
@ -230,6 +231,7 @@ public class SearchFragment extends Fragment {
|
||||
Timber.d("onQueryTextSubmit: %s", query);
|
||||
mergeAdapter = new MergeAdapter();
|
||||
list.setAdapter(mergeAdapter);
|
||||
searchView.clearFocus();
|
||||
search(query, autoPlay);
|
||||
return true;
|
||||
}
|
||||
@ -243,9 +245,11 @@ public class SearchFragment extends Fragment {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo)
|
||||
public void onCreateContextMenu(@NotNull ContextMenu menu, @NotNull View view, ContextMenu.ContextMenuInfo menuInfo)
|
||||
{
|
||||
super.onCreateContextMenu(menu, view, menuInfo);
|
||||
if (getActivity() == null) return;
|
||||
|
||||
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
Object selectedItem = list.getItemAtPosition(info.position);
|
||||
|
||||
@ -311,84 +315,65 @@ public class SearchFragment extends Fragment {
|
||||
|
||||
List<MusicDirectory.Entry> songs = new ArrayList<>(1);
|
||||
|
||||
switch (menuItem.getItemId())
|
||||
{
|
||||
case R.id.album_menu_play_now:
|
||||
downloadHandler.getValue().downloadRecursively(this, id, false, false, true, false, false, false, false, false);
|
||||
break;
|
||||
case R.id.album_menu_play_next:
|
||||
downloadHandler.getValue().downloadRecursively(this, id, false, true, false, true, false, true, false, false);
|
||||
break;
|
||||
case R.id.album_menu_play_last:
|
||||
downloadHandler.getValue().downloadRecursively(this, id, false, true, false, false, false, false, false, false);
|
||||
break;
|
||||
case R.id.album_menu_pin:
|
||||
downloadHandler.getValue().downloadRecursively(this, id, true, true, false, false, false, false, false, false);
|
||||
break;
|
||||
case R.id.album_menu_unpin:
|
||||
downloadHandler.getValue().downloadRecursively(this, id, false, false, false, false, false, false, true, false);
|
||||
break;
|
||||
case R.id.album_menu_download:
|
||||
downloadHandler.getValue().downloadRecursively(this, id, false, false, false, false, true, false, false, false);
|
||||
break;
|
||||
case R.id.song_menu_play_now:
|
||||
if (entry != null)
|
||||
{
|
||||
songs = new ArrayList<>(1);
|
||||
songs.add(entry);
|
||||
downloadHandler.getValue().download(this, false, false, true, false, false, songs);
|
||||
}
|
||||
break;
|
||||
case R.id.song_menu_play_next:
|
||||
if (entry != null)
|
||||
{
|
||||
songs = new ArrayList<>(1);
|
||||
songs.add(entry);
|
||||
downloadHandler.getValue().download(this, true, false, false, true, false, songs);
|
||||
}
|
||||
break;
|
||||
case R.id.song_menu_play_last:
|
||||
if (entry != null)
|
||||
{
|
||||
songs = new ArrayList<>(1);
|
||||
songs.add(entry);
|
||||
downloadHandler.getValue().download(this, true, false, false, false, false, songs);
|
||||
}
|
||||
break;
|
||||
case R.id.song_menu_pin:
|
||||
if (entry != null)
|
||||
{
|
||||
songs.add(entry);
|
||||
Util.toast(getContext(), getResources().getQuantityString(R.plurals.select_album_n_songs_pinned, songs.size(), songs.size()));
|
||||
downloadBackground(true, songs);
|
||||
}
|
||||
break;
|
||||
case R.id.song_menu_download:
|
||||
if (entry != null)
|
||||
{
|
||||
songs.add(entry);
|
||||
Util.toast(getContext(), getResources().getQuantityString(R.plurals.select_album_n_songs_downloaded, songs.size(), songs.size()));
|
||||
downloadBackground(false, songs);
|
||||
}
|
||||
break;
|
||||
case R.id.song_menu_unpin:
|
||||
if (entry != null)
|
||||
{
|
||||
songs.add(entry);
|
||||
Util.toast(getContext(), getResources().getQuantityString(R.plurals.select_album_n_songs_unpinned, songs.size(), songs.size()));
|
||||
mediaPlayerControllerLazy.getValue().unpin(songs);
|
||||
}
|
||||
break;
|
||||
case R.id.menu_item_share:
|
||||
if (entry != null)
|
||||
{
|
||||
songs = new ArrayList<>(1);
|
||||
songs.add(entry);
|
||||
// TODO: Add SwipeRefresh spinner
|
||||
shareHandler.getValue().createShare(this, songs, null, cancellationToken);
|
||||
}
|
||||
default:
|
||||
return super.onContextItemSelected(menuItem);
|
||||
int itemId = menuItem.getItemId();
|
||||
if (itemId == R.id.album_menu_play_now) {
|
||||
downloadHandler.getValue().downloadRecursively(this, id, false, false, true, false, false, false, false, false);
|
||||
} else if (itemId == R.id.album_menu_play_next) {
|
||||
downloadHandler.getValue().downloadRecursively(this, id, false, true, false, true, false, true, false, false);
|
||||
} else if (itemId == R.id.album_menu_play_last) {
|
||||
downloadHandler.getValue().downloadRecursively(this, id, false, true, false, false, false, false, false, false);
|
||||
} else if (itemId == R.id.album_menu_pin) {
|
||||
downloadHandler.getValue().downloadRecursively(this, id, true, true, false, false, false, false, false, false);
|
||||
} else if (itemId == R.id.album_menu_unpin) {
|
||||
downloadHandler.getValue().downloadRecursively(this, id, false, false, false, false, false, false, true, false);
|
||||
} else if (itemId == R.id.album_menu_download) {
|
||||
downloadHandler.getValue().downloadRecursively(this, id, false, false, false, false, true, false, false, false);
|
||||
} else if (itemId == R.id.song_menu_play_now) {
|
||||
if (entry != null) {
|
||||
songs = new ArrayList<>(1);
|
||||
songs.add(entry);
|
||||
downloadHandler.getValue().download(this, false, false, true, false, false, songs);
|
||||
}
|
||||
} else if (itemId == R.id.song_menu_play_next) {
|
||||
if (entry != null) {
|
||||
songs = new ArrayList<>(1);
|
||||
songs.add(entry);
|
||||
downloadHandler.getValue().download(this, true, false, false, true, false, songs);
|
||||
}
|
||||
} else if (itemId == R.id.song_menu_play_last) {
|
||||
if (entry != null) {
|
||||
songs = new ArrayList<>(1);
|
||||
songs.add(entry);
|
||||
downloadHandler.getValue().download(this, true, false, false, false, false, songs);
|
||||
}
|
||||
} else if (itemId == R.id.song_menu_pin) {
|
||||
if (entry != null) {
|
||||
songs.add(entry);
|
||||
Util.toast(getContext(), getResources().getQuantityString(R.plurals.select_album_n_songs_pinned, songs.size(), songs.size()));
|
||||
downloadBackground(true, songs);
|
||||
}
|
||||
} else if (itemId == R.id.song_menu_download) {
|
||||
if (entry != null) {
|
||||
songs.add(entry);
|
||||
Util.toast(getContext(), getResources().getQuantityString(R.plurals.select_album_n_songs_downloaded, songs.size(), songs.size()));
|
||||
downloadBackground(false, songs);
|
||||
}
|
||||
} else if (itemId == R.id.song_menu_unpin) {
|
||||
if (entry != null) {
|
||||
songs.add(entry);
|
||||
Util.toast(getContext(), getResources().getQuantityString(R.plurals.select_album_n_songs_unpinned, songs.size(), songs.size()));
|
||||
mediaPlayerControllerLazy.getValue().unpin(songs);
|
||||
}
|
||||
} else if (itemId == R.id.menu_item_share) {
|
||||
if (entry != null) {
|
||||
songs = new ArrayList<>(1);
|
||||
songs.add(entry);
|
||||
shareHandler.getValue().createShare(this, songs, searchRefresh, cancellationToken);
|
||||
}
|
||||
|
||||
return super.onContextItemSelected(menuItem);
|
||||
} else {
|
||||
return super.onContextItemSelected(menuItem);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -421,14 +406,14 @@ public class SearchFragment extends Fragment {
|
||||
final int maxAlbums = Util.getMaxAlbums(getContext());
|
||||
final int maxSongs = Util.getMaxSongs(getContext());
|
||||
|
||||
BackgroundTask<SearchResult> task = new TabActivityBackgroundTask<SearchResult>(getActivity(), true, searchRefresh, cancellationToken)
|
||||
BackgroundTask<SearchResult> task = new FragmentBackgroundTask<SearchResult>(getActivity(), true, searchRefresh, cancellationToken)
|
||||
{
|
||||
@Override
|
||||
protected SearchResult doInBackground() throws Throwable
|
||||
{
|
||||
SearchCriteria criteria = new SearchCriteria(query, maxArtists, maxAlbums, maxSongs);
|
||||
MusicService service = MusicServiceFactory.getMusicService(getContext());
|
||||
return service.search(criteria, getContext(), this);
|
||||
return service.search(criteria, getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -452,16 +437,13 @@ public class SearchFragment extends Fragment {
|
||||
{
|
||||
mergeAdapter = new MergeAdapter();
|
||||
|
||||
// TODO: Remove this if the search widget can do the same
|
||||
//mergeAdapter.addView(searchButton, true);
|
||||
|
||||
if (searchResult != null)
|
||||
{
|
||||
List<Artist> artists = searchResult.getArtists();
|
||||
if (!artists.isEmpty())
|
||||
{
|
||||
mergeAdapter.addView(artistsHeading);
|
||||
List<Artist> displayedArtists = new ArrayList<Artist>(artists.subList(0, Math.min(DEFAULT_ARTISTS, artists.size())));
|
||||
List<Artist> displayedArtists = new ArrayList<>(artists.subList(0, Math.min(DEFAULT_ARTISTS, artists.size())));
|
||||
artistAdapter = new ArtistAdapter(getContext(), displayedArtists);
|
||||
mergeAdapter.addAdapter(artistAdapter);
|
||||
if (artists.size() > DEFAULT_ARTISTS)
|
||||
@ -474,7 +456,7 @@ public class SearchFragment extends Fragment {
|
||||
if (!albums.isEmpty())
|
||||
{
|
||||
mergeAdapter.addView(albumsHeading);
|
||||
List<MusicDirectory.Entry> displayedAlbums = new ArrayList<MusicDirectory.Entry>(albums.subList(0, Math.min(DEFAULT_ALBUMS, albums.size())));
|
||||
List<MusicDirectory.Entry> displayedAlbums = new ArrayList<>(albums.subList(0, Math.min(DEFAULT_ALBUMS, albums.size())));
|
||||
albumAdapter = new EntryAdapter(getContext(), imageLoaderProvider.getValue().getImageLoader(), displayedAlbums, false);
|
||||
mergeAdapter.addAdapter(albumAdapter);
|
||||
if (albums.size() > DEFAULT_ALBUMS)
|
||||
@ -487,7 +469,7 @@ public class SearchFragment extends Fragment {
|
||||
if (!songs.isEmpty())
|
||||
{
|
||||
mergeAdapter.addView(songsHeading);
|
||||
List<MusicDirectory.Entry> displayedSongs = new ArrayList<MusicDirectory.Entry>(songs.subList(0, Math.min(DEFAULT_SONGS, songs.size())));
|
||||
List<MusicDirectory.Entry> displayedSongs = new ArrayList<>(songs.subList(0, Math.min(DEFAULT_SONGS, songs.size())));
|
||||
songAdapter = new EntryAdapter(getContext(), imageLoaderProvider.getValue().getImageLoader(), displayedSongs, false);
|
||||
mergeAdapter.addAdapter(songAdapter);
|
||||
if (songs.size() > DEFAULT_SONGS)
|
||||
|
@ -39,7 +39,7 @@ import org.moire.ultrasonic.util.CancellationToken;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.EntryByDiscAndTrackComparator;
|
||||
import org.moire.ultrasonic.util.Pair;
|
||||
import org.moire.ultrasonic.util.TabActivityBackgroundTask;
|
||||
import org.moire.ultrasonic.util.FragmentBackgroundTask;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
import org.moire.ultrasonic.view.AlbumView;
|
||||
import org.moire.ultrasonic.view.EntryAdapter;
|
||||
@ -152,7 +152,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
});
|
||||
|
||||
// TODO: Long click on an item will first try to maximize / collapse the item, even when it fits inside the TextView.
|
||||
// The context menu is only displayed on the second long click...
|
||||
// The context menu is only displayed on the second long click... This may be improved somehow, e.g. checking first if the texts fit
|
||||
albumListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener(){
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
@ -258,7 +258,11 @@ public class SelectAlbumFragment extends Fragment {
|
||||
registerForContextMenu(albumListView);
|
||||
setHasOptionsMenu(true);
|
||||
enableButtons();
|
||||
updateDisplay(false);
|
||||
}
|
||||
|
||||
private void updateDisplay(boolean refresh)
|
||||
{
|
||||
String id = getArguments().getString(Constants.INTENT_EXTRA_NAME_ID);
|
||||
boolean isAlbum = getArguments().getBoolean(Constants.INTENT_EXTRA_NAME_IS_ALBUM, false);
|
||||
String name = getArguments().getString(Constants.INTENT_EXTRA_NAME_NAME);
|
||||
@ -302,7 +306,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
}
|
||||
else if (getVideos != 0)
|
||||
{
|
||||
getVideos();
|
||||
getVideos(refresh);
|
||||
}
|
||||
else if (getRandomTracks != 0)
|
||||
{
|
||||
@ -314,16 +318,16 @@ public class SelectAlbumFragment extends Fragment {
|
||||
{
|
||||
if (isAlbum)
|
||||
{
|
||||
getAlbum(id, name, parentId);
|
||||
getAlbum(refresh, id, name, parentId);
|
||||
}
|
||||
else
|
||||
{
|
||||
getArtist(id, name);
|
||||
getArtist(refresh, id, name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
getMusicDirectory(id, name, parentId);
|
||||
getMusicDirectory(refresh, id, name, parentId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -377,36 +381,28 @@ public class SelectAlbumFragment extends Fragment {
|
||||
|
||||
String entryId = entry.getId();
|
||||
|
||||
switch (menuItem.getItemId())
|
||||
{
|
||||
case R.id.album_menu_play_now:
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, false, false, true, false, false, false, false, false);
|
||||
break;
|
||||
case R.id.album_menu_play_next:
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, false, false, false, false, false, true, false, false);
|
||||
break;
|
||||
case R.id.album_menu_play_last:
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, false, true, false, false, false, false, false, false);
|
||||
break;
|
||||
case R.id.album_menu_pin:
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, true, true, false, false, false, false, false, false);
|
||||
break;
|
||||
case R.id.album_menu_unpin:
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, false, false, false, false, false, false, true, false);
|
||||
break;
|
||||
case R.id.album_menu_download:
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, false, false, false, false, true, false, false, false);
|
||||
break;
|
||||
case R.id.select_album_play_all:
|
||||
playAll();
|
||||
break;
|
||||
case R.id.menu_item_share:
|
||||
List<MusicDirectory.Entry> entries = new ArrayList<MusicDirectory.Entry>(1);
|
||||
entries.add(entry);
|
||||
shareHandler.getValue().createShare(this, entries, refreshAlbumListView, cancellationToken);
|
||||
return true;
|
||||
default:
|
||||
return super.onContextItemSelected(menuItem);
|
||||
int itemId = menuItem.getItemId();
|
||||
if (itemId == R.id.album_menu_play_now) {
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, false, false, true, false, false, false, false, false);
|
||||
} else if (itemId == R.id.album_menu_play_next) {
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, false, false, false, false, false, true, false, false);
|
||||
} else if (itemId == R.id.album_menu_play_last) {
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, false, true, false, false, false, false, false, false);
|
||||
} else if (itemId == R.id.album_menu_pin) {
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, true, true, false, false, false, false, false, false);
|
||||
} else if (itemId == R.id.album_menu_unpin) {
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, false, false, false, false, false, false, true, false);
|
||||
} else if (itemId == R.id.album_menu_download) {
|
||||
downloadHandler.getValue().downloadRecursively(this, entryId, false, false, false, false, true, false, false, false);
|
||||
} else if (itemId == R.id.select_album_play_all) {
|
||||
playAll();
|
||||
} else if (itemId == R.id.menu_item_share) {
|
||||
List<MusicDirectory.Entry> entries = new ArrayList<MusicDirectory.Entry>(1);
|
||||
entries.add(entry);
|
||||
shareHandler.getValue().createShare(this, entries, refreshAlbumListView, cancellationToken);
|
||||
return true;
|
||||
} else {
|
||||
return super.onContextItemSelected(menuItem);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -439,14 +435,13 @@ public class SelectAlbumFragment extends Fragment {
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item)
|
||||
{
|
||||
switch (item.getItemId())
|
||||
{
|
||||
case R.id.select_album_play_all:
|
||||
playAll();
|
||||
return true;
|
||||
case R.id.menu_item_share:
|
||||
shareHandler.getValue().createShare(this, getSelectedSongs(albumListView), refreshAlbumListView, cancellationToken);
|
||||
return true;
|
||||
int itemId = item.getItemId();
|
||||
if (itemId == R.id.select_album_play_all) {
|
||||
playAll();
|
||||
return true;
|
||||
} else if (itemId == R.id.menu_item_share) {
|
||||
shareHandler.getValue().createShare(this, getSelectedSongs(albumListView), refreshAlbumListView, cancellationToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -528,25 +523,16 @@ public class SelectAlbumFragment extends Fragment {
|
||||
|
||||
private void refresh()
|
||||
{
|
||||
// TODO: create better restart
|
||||
getView().post(new Runnable() {
|
||||
public void run() {
|
||||
Timber.d("Refresh called...");
|
||||
getArguments().putBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
onViewCreated(getView(), null);
|
||||
updateDisplay(true);
|
||||
}
|
||||
});
|
||||
|
||||
/*finish();
|
||||
Intent intent = getArguments();
|
||||
intent.putExtra(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
startActivityForResultWithoutTransition(this, intent);*/
|
||||
}
|
||||
|
||||
private void getMusicDirectory(final String id, final String name, final String parentId)
|
||||
private void getMusicDirectory(final boolean refresh, final String id, final String name, final String parentId)
|
||||
{
|
||||
FragmentTitle.Companion.setTitle(this, name);
|
||||
//setActionBarSubtitle(name);
|
||||
|
||||
new LoadTask()
|
||||
{
|
||||
@ -557,8 +543,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
|
||||
if (allSongsId.equals(id))
|
||||
{
|
||||
boolean refresh = getArguments().getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, false);
|
||||
MusicDirectory musicDirectory = service.getMusicDirectory(parentId, name, refresh, getContext(), this);
|
||||
MusicDirectory musicDirectory = service.getMusicDirectory(parentId, name, refresh, getContext());
|
||||
|
||||
List<MusicDirectory.Entry> songs = new LinkedList<MusicDirectory.Entry>();
|
||||
getSongsRecursively(musicDirectory, songs);
|
||||
@ -573,8 +558,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean refresh = getArguments().getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, false);
|
||||
MusicDirectory musicDirectory = service.getMusicDirectory(id, name, refresh, getContext(), this);
|
||||
MusicDirectory musicDirectory = service.getMusicDirectory(id, name, refresh, getContext());
|
||||
|
||||
if (Util.getShouldShowAllSongsByArtist(getContext()) && musicDirectory.findChild(allSongsId) == null && musicDirectory.getChildren(true, false).size() == musicDirectory.getChildren(true, true).size())
|
||||
{
|
||||
@ -622,7 +606,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
|
||||
if (!allSongsId.equals(dir.getId()))
|
||||
{
|
||||
root = musicService.getMusicDirectory(dir.getId(), dir.getTitle(), false, getContext(), this);
|
||||
root = musicService.getMusicDirectory(dir.getId(), dir.getTitle(), false, getContext());
|
||||
|
||||
getSongsRecursively(root, songs);
|
||||
}
|
||||
@ -631,10 +615,9 @@ public class SelectAlbumFragment extends Fragment {
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private void getArtist(final String id, final String name)
|
||||
private void getArtist(final boolean refresh, final String id, final String name)
|
||||
{
|
||||
FragmentTitle.Companion.setTitle(this, name);
|
||||
//setActionBarSubtitle(name);
|
||||
|
||||
new LoadTask()
|
||||
{
|
||||
@ -643,8 +626,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
{
|
||||
MusicDirectory root = new MusicDirectory();
|
||||
|
||||
boolean refresh = getArguments().getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, false);
|
||||
MusicDirectory musicDirectory = service.getArtist(id, name, refresh, getContext(), this);
|
||||
MusicDirectory musicDirectory = service.getArtist(id, name, refresh, getContext());
|
||||
|
||||
if (Util.getShouldShowAllSongsByArtist(getContext()) && musicDirectory.findChild(allSongsId) == null && musicDirectory.getChildren(true, false).size() == musicDirectory.getChildren(true, true).size())
|
||||
{
|
||||
@ -675,10 +657,9 @@ public class SelectAlbumFragment extends Fragment {
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private void getAlbum(final String id, final String name, final String parentId)
|
||||
private void getAlbum(final boolean refresh, final String id, final String name, final String parentId)
|
||||
{
|
||||
FragmentTitle.Companion.setTitle(this, name);
|
||||
//setActionBarSubtitle(name);
|
||||
|
||||
new LoadTask()
|
||||
{
|
||||
@ -687,8 +668,6 @@ public class SelectAlbumFragment extends Fragment {
|
||||
{
|
||||
MusicDirectory musicDirectory;
|
||||
|
||||
boolean refresh = getArguments().getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, false);
|
||||
|
||||
if (allSongsId.equals(id))
|
||||
{
|
||||
MusicDirectory root = new MusicDirectory();
|
||||
@ -708,7 +687,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
}
|
||||
else
|
||||
{
|
||||
musicDirectory = service.getAlbum(id, name, refresh, getContext(), this);
|
||||
musicDirectory = service.getAlbum(id, name, refresh, getContext());
|
||||
}
|
||||
|
||||
return musicDirectory;
|
||||
@ -717,13 +696,13 @@ public class SelectAlbumFragment extends Fragment {
|
||||
private void getSongsForArtist(String id, Collection<MusicDirectory.Entry> songs) throws Exception
|
||||
{
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
MusicDirectory artist = musicService.getArtist(id, "", false, getContext(), this);
|
||||
MusicDirectory artist = musicService.getArtist(id, "", false, getContext());
|
||||
|
||||
for (MusicDirectory.Entry album : artist.getChildren())
|
||||
{
|
||||
if (!allSongsId.equals(album.getId()))
|
||||
{
|
||||
MusicDirectory albumDirectory = musicService.getAlbum(album.getId(), "", false, getContext(), this);
|
||||
MusicDirectory albumDirectory = musicService.getAlbum(album.getId(), "", false, getContext());
|
||||
|
||||
for (MusicDirectory.Entry song : albumDirectory.getChildren())
|
||||
{
|
||||
@ -741,14 +720,13 @@ public class SelectAlbumFragment extends Fragment {
|
||||
private void getSongsForGenre(final String genre, final int count, final int offset)
|
||||
{
|
||||
FragmentTitle.Companion.setTitle(this, genre);
|
||||
//setActionBarSubtitle(genre);
|
||||
|
||||
new LoadTask()
|
||||
{
|
||||
@Override
|
||||
protected MusicDirectory load(MusicService service) throws Exception
|
||||
{
|
||||
return service.getSongsByGenre(genre, count, offset, getContext(), this);
|
||||
return service.getSongsByGenre(genre, count, offset, getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -789,32 +767,29 @@ public class SelectAlbumFragment extends Fragment {
|
||||
private void getStarred()
|
||||
{
|
||||
FragmentTitle.Companion.setTitle(this, R.string.main_songs_starred);
|
||||
//setActionBarSubtitle(R.string.main_songs_starred);
|
||||
|
||||
new LoadTask()
|
||||
{
|
||||
@Override
|
||||
protected MusicDirectory load(MusicService service) throws Exception
|
||||
{
|
||||
return Util.getShouldUseId3Tags(getContext()) ? Util.getSongsFromSearchResult(service.getStarred2(getContext(), this)) : Util.getSongsFromSearchResult(service.getStarred(getContext(), this));
|
||||
return Util.getShouldUseId3Tags(getContext()) ? Util.getSongsFromSearchResult(service.getStarred2(getContext())) : Util.getSongsFromSearchResult(service.getStarred(getContext()));
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private void getVideos()
|
||||
private void getVideos(final boolean refresh)
|
||||
{
|
||||
showHeader = false;
|
||||
|
||||
FragmentTitle.Companion.setTitle(this, R.string.main_videos);
|
||||
//setActionBarSubtitle(R.string.main_videos);
|
||||
|
||||
new LoadTask()
|
||||
{
|
||||
@Override
|
||||
protected MusicDirectory load(MusicService service) throws Exception
|
||||
{
|
||||
boolean refresh = getArguments().getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, false);
|
||||
return service.getVideos(refresh, getContext(), this);
|
||||
return service.getVideos(refresh, getContext());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
@ -822,7 +797,6 @@ public class SelectAlbumFragment extends Fragment {
|
||||
private void getRandom(final int size)
|
||||
{
|
||||
FragmentTitle.Companion.setTitle(this, R.string.main_songs_random);
|
||||
//setActionBarSubtitle(R.string.main_songs_random);
|
||||
|
||||
new LoadTask()
|
||||
{
|
||||
@ -834,7 +808,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
@Override
|
||||
protected MusicDirectory load(MusicService service) throws Exception
|
||||
{
|
||||
return service.getRandomSongs(size, getContext(), this);
|
||||
return service.getRandomSongs(size, getContext());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
@ -842,29 +816,27 @@ public class SelectAlbumFragment extends Fragment {
|
||||
private void getPlaylist(final String playlistId, final String playlistName)
|
||||
{
|
||||
FragmentTitle.Companion.setTitle(this, playlistName);
|
||||
//setActionBarSubtitle(playlistName);
|
||||
|
||||
new LoadTask()
|
||||
{
|
||||
@Override
|
||||
protected MusicDirectory load(MusicService service) throws Exception
|
||||
{
|
||||
return service.getPlaylist(playlistId, playlistName, getContext(), this);
|
||||
return service.getPlaylist(playlistId, playlistName, getContext());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
private void getPodcastEpisodes(final String podcastChannelId)
|
||||
{
|
||||
// TODO: Not sure what the title should be for a podcast episode. Maybe a constant string should be used.
|
||||
//setActionBarSubtitle(playlistName);
|
||||
FragmentTitle.Companion.setTitle(this, R.string.podcasts_label);
|
||||
|
||||
new LoadTask()
|
||||
{
|
||||
@Override
|
||||
protected MusicDirectory load(MusicService service) throws Exception
|
||||
{
|
||||
return service.getPodcastEpisodes(podcastChannelId, getContext(), this);
|
||||
return service.getPodcastEpisodes(podcastChannelId, getContext());
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
@ -879,7 +851,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
@Override
|
||||
protected MusicDirectory load(MusicService service) throws Exception
|
||||
{
|
||||
List<Share> shares = service.getShares(true, getContext(), this);
|
||||
List<Share> shares = service.getShares(true, getContext());
|
||||
|
||||
MusicDirectory md = new MusicDirectory();
|
||||
|
||||
@ -920,7 +892,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
@Override
|
||||
protected MusicDirectory load(MusicService service) throws Exception
|
||||
{
|
||||
return Util.getShouldUseId3Tags(getContext()) ? service.getAlbumList2(albumListType, size, offset, getContext(), this) : service.getAlbumList(albumListType, size, offset, getContext(), this);
|
||||
return Util.getShouldUseId3Tags(getContext()) ? service.getAlbumList2(albumListType, size, offset, getContext()) : service.getAlbumList(albumListType, size, offset, getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1103,7 +1075,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
mediaPlayerControllerLazy.getValue().unpin(songs);
|
||||
}
|
||||
|
||||
private abstract class LoadTask extends TabActivityBackgroundTask<Pair<MusicDirectory, Boolean>>
|
||||
private abstract class LoadTask extends FragmentBackgroundTask<Pair<MusicDirectory, Boolean>>
|
||||
{
|
||||
|
||||
public LoadTask()
|
||||
@ -1122,7 +1094,7 @@ public class SelectAlbumFragment extends Fragment {
|
||||
{
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
MusicDirectory dir = load(musicService);
|
||||
boolean valid = musicService.isLicenseValid(getContext(), this);
|
||||
boolean valid = musicService.isLicenseValid(getContext());
|
||||
return new Pair<MusicDirectory, Boolean>(dir, valid);
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ import org.moire.ultrasonic.service.MusicServiceFactory;
|
||||
import org.moire.ultrasonic.util.BackgroundTask;
|
||||
import org.moire.ultrasonic.util.CancellationToken;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.TabActivityBackgroundTask;
|
||||
import org.moire.ultrasonic.util.FragmentBackgroundTask;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
import org.moire.ultrasonic.view.GenreAdapter;
|
||||
|
||||
@ -75,7 +75,7 @@ public class SelectGenreFragment extends Fragment {
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_GENRE_NAME, genre.getName());
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, Util.getMaxSongs(getContext()));
|
||||
bundle.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0);
|
||||
Navigation.findNavController(getView()).navigate(R.id.selectAlbumFragment, bundle);
|
||||
Navigation.findNavController(view).navigate(R.id.selectAlbumFragment, bundle);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -84,8 +84,7 @@ public class SelectGenreFragment extends Fragment {
|
||||
registerForContextMenu(genreListView);
|
||||
|
||||
FragmentTitle.Companion.setTitle(this, R.string.main_genres_title);
|
||||
|
||||
load();
|
||||
load(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -96,43 +95,23 @@ public class SelectGenreFragment extends Fragment {
|
||||
|
||||
private void refresh()
|
||||
{
|
||||
// TODO: create better restart
|
||||
getView().post(new Runnable() {
|
||||
public void run() {
|
||||
Timber.d("Refresh called...");
|
||||
if (getArguments() == null) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
setArguments(bundle);
|
||||
} else {
|
||||
getArguments().putBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
}
|
||||
onViewCreated(getView(), null);
|
||||
}
|
||||
});
|
||||
/* finish();
|
||||
Intent intent = getIntent();
|
||||
intent.putExtra(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
startActivityForResultWithoutTransition(this, intent);
|
||||
|
||||
*/
|
||||
load(true);
|
||||
}
|
||||
|
||||
private void load()
|
||||
private void load(final boolean refresh)
|
||||
{
|
||||
BackgroundTask<List<Genre>> task = new TabActivityBackgroundTask<List<Genre>>(getActivity(), true, refreshGenreListView, cancellationToken)
|
||||
BackgroundTask<List<Genre>> task = new FragmentBackgroundTask<List<Genre>>(getActivity(), true, refreshGenreListView, cancellationToken)
|
||||
{
|
||||
@Override
|
||||
protected List<Genre> doInBackground() throws Throwable
|
||||
{
|
||||
boolean refresh = getArguments() != null && getArguments().getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, false);
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
|
||||
List<Genre> genres = new ArrayList<Genre>();
|
||||
|
||||
try
|
||||
{
|
||||
genres = musicService.getGenres(refresh, getContext(), this);
|
||||
genres = musicService.getGenres(refresh, getContext());
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
|
@ -2,7 +2,6 @@ package org.moire.ultrasonic.fragment;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
@ -40,7 +39,7 @@ import org.moire.ultrasonic.util.BackgroundTask;
|
||||
import org.moire.ultrasonic.util.CancellationToken;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.LoadingTask;
|
||||
import org.moire.ultrasonic.util.TabActivityBackgroundTask;
|
||||
import org.moire.ultrasonic.util.FragmentBackgroundTask;
|
||||
import org.moire.ultrasonic.util.TimeSpan;
|
||||
import org.moire.ultrasonic.util.TimeSpanPicker;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
@ -49,7 +48,6 @@ import org.moire.ultrasonic.view.ShareAdapter;
|
||||
import java.util.List;
|
||||
|
||||
import kotlin.Lazy;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static org.koin.java.KoinJavaComponent.inject;
|
||||
|
||||
@ -105,14 +103,13 @@ public class SharesFragment extends Fragment {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_SHARE_ID, share.getId());
|
||||
bundle.putString(Constants.INTENT_EXTRA_NAME_SHARE_NAME, share.getName());
|
||||
Navigation.findNavController(getView()).navigate(R.id.selectAlbumFragment, bundle);
|
||||
Navigation.findNavController(view).navigate(R.id.selectAlbumFragment, bundle);
|
||||
}
|
||||
});
|
||||
registerForContextMenu(sharesListView);
|
||||
|
||||
FragmentTitle.Companion.setTitle(this, R.string.button_bar_shares);
|
||||
|
||||
load();
|
||||
load(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -123,39 +120,18 @@ public class SharesFragment extends Fragment {
|
||||
|
||||
private void refresh()
|
||||
{
|
||||
// TODO: create better restart
|
||||
getView().post(new Runnable() {
|
||||
public void run() {
|
||||
Timber.d("Refresh called...");
|
||||
if (getArguments() == null) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
setArguments(bundle);
|
||||
} else {
|
||||
getArguments().putBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
}
|
||||
onViewCreated(getView(), null);
|
||||
}
|
||||
});
|
||||
|
||||
/* finish();
|
||||
Intent intent = new Intent(this, ShareActivity.class);
|
||||
intent.putExtra(Constants.INTENT_EXTRA_NAME_REFRESH, true);
|
||||
startActivityForResultWithoutTransition(this, intent);
|
||||
|
||||
*/
|
||||
load(true);
|
||||
}
|
||||
|
||||
private void load()
|
||||
private void load(final boolean refresh)
|
||||
{
|
||||
BackgroundTask<List<Share>> task = new TabActivityBackgroundTask<List<Share>>(getActivity(), true, refreshSharesListView, cancellationToken)
|
||||
BackgroundTask<List<Share>> task = new FragmentBackgroundTask<List<Share>>(getActivity(), true, refreshSharesListView, cancellationToken)
|
||||
{
|
||||
@Override
|
||||
protected List<Share> doInBackground() throws Throwable
|
||||
{
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
boolean refresh = getArguments() != null && getArguments().getBoolean(Constants.INTENT_EXTRA_NAME_REFRESH, false);
|
||||
return musicService.getShares(refresh, getContext(), this);
|
||||
return musicService.getShares(refresh, getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -181,45 +157,30 @@ public class SharesFragment extends Fragment {
|
||||
public boolean onContextItemSelected(MenuItem menuItem)
|
||||
{
|
||||
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuItem.getMenuInfo();
|
||||
if (info == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (info == null) return false;
|
||||
|
||||
Share share = (Share) sharesListView.getItemAtPosition(info.position);
|
||||
if (share == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (share == null || share.getId() == null) return false;
|
||||
|
||||
switch (menuItem.getItemId())
|
||||
{
|
||||
case R.id.share_menu_pin:
|
||||
downloadHandler.getValue().downloadShare(this, share.getId(), share.getName(), true, true, false, false, true, false, false);
|
||||
break;
|
||||
case R.id.share_menu_unpin:
|
||||
downloadHandler.getValue().downloadShare(this, share.getId(), share.getName(), false, false, false, false, true, false, true);
|
||||
break;
|
||||
case R.id.share_menu_download:
|
||||
downloadHandler.getValue().downloadShare(this, share.getId(), share.getName(), false, false, false, false, true, false, false);
|
||||
break;
|
||||
case R.id.share_menu_play_now:
|
||||
downloadHandler.getValue().downloadShare(this, share.getId(), share.getName(), false, false, true, false, false, false, false);
|
||||
break;
|
||||
case R.id.share_menu_play_shuffled:
|
||||
downloadHandler.getValue().downloadShare(this, share.getId(), share.getName(), false, false, true, true, false, false, false);
|
||||
break;
|
||||
case R.id.share_menu_delete:
|
||||
deleteShare(share);
|
||||
break;
|
||||
case R.id.share_info:
|
||||
displayShareInfo(share);
|
||||
break;
|
||||
case R.id.share_update_info:
|
||||
updateShareInfo(share);
|
||||
break;
|
||||
default:
|
||||
return super.onContextItemSelected(menuItem);
|
||||
int itemId = menuItem.getItemId();
|
||||
if (itemId == R.id.share_menu_pin) {
|
||||
downloadHandler.getValue().downloadShare(this, share.getId(), share.getName(), true, true, false, false, true, false, false);
|
||||
} else if (itemId == R.id.share_menu_unpin) {
|
||||
downloadHandler.getValue().downloadShare(this, share.getId(), share.getName(), false, false, false, false, true, false, true);
|
||||
} else if (itemId == R.id.share_menu_download) {
|
||||
downloadHandler.getValue().downloadShare(this, share.getId(), share.getName(), false, false, false, false, true, false, false);
|
||||
} else if (itemId == R.id.share_menu_play_now) {
|
||||
downloadHandler.getValue().downloadShare(this, share.getId(), share.getName(), false, false, true, false, false, false, false);
|
||||
} else if (itemId == R.id.share_menu_play_shuffled) {
|
||||
downloadHandler.getValue().downloadShare(this, share.getId(), share.getName(), false, false, true, true, false, false, false);
|
||||
} else if (itemId == R.id.share_menu_delete) {
|
||||
deleteShare(share);
|
||||
} else if (itemId == R.id.share_info) {
|
||||
displayShareInfo(share);
|
||||
} else if (itemId == R.id.share_update_info) {
|
||||
updateShareInfo(share);
|
||||
} else {
|
||||
return super.onContextItemSelected(menuItem);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -237,7 +198,7 @@ public class SharesFragment extends Fragment {
|
||||
protected Void doInBackground() throws Throwable
|
||||
{
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
musicService.deleteShare(share.getId(), getContext(), null);
|
||||
musicService.deleteShare(share.getId(), getContext());
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -343,7 +304,7 @@ public class SharesFragment extends Fragment {
|
||||
String description = shareDescriptionText != null ? shareDescriptionText.toString() : null;
|
||||
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(getContext());
|
||||
musicService.updateShare(share.getId(), description, millis, getContext(), null);
|
||||
musicService.updateShare(share.getId(), description, millis, getContext());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,6 @@ import org.moire.ultrasonic.domain.UserInfo;
|
||||
import org.moire.ultrasonic.util.CancellableTask;
|
||||
import org.moire.ultrasonic.util.Constants;
|
||||
import org.moire.ultrasonic.util.LRUCache;
|
||||
import org.moire.ultrasonic.util.ProgressListener;
|
||||
import org.moire.ultrasonic.util.TimeLimitedCache;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
|
||||
@ -59,7 +58,7 @@ import static org.koin.java.KoinJavaComponent.inject;
|
||||
*/
|
||||
public class CachedMusicService implements MusicService
|
||||
{
|
||||
private Lazy<ActiveServerProvider> activeServerProvider = inject(ActiveServerProvider.class);
|
||||
private final Lazy<ActiveServerProvider> activeServerProvider = inject(ActiveServerProvider.class);
|
||||
|
||||
private static final int MUSIC_DIR_CACHE_SIZE = 100;
|
||||
|
||||
@ -81,36 +80,36 @@ public class CachedMusicService implements MusicService
|
||||
public CachedMusicService(MusicService musicService)
|
||||
{
|
||||
this.musicService = musicService;
|
||||
cachedMusicDirectories = new LRUCache<String, TimeLimitedCache<MusicDirectory>>(MUSIC_DIR_CACHE_SIZE);
|
||||
cachedArtist = new LRUCache<String, TimeLimitedCache<MusicDirectory>>(MUSIC_DIR_CACHE_SIZE);
|
||||
cachedAlbum = new LRUCache<String, TimeLimitedCache<MusicDirectory>>(MUSIC_DIR_CACHE_SIZE);
|
||||
cachedUserInfo = new LRUCache<String, TimeLimitedCache<UserInfo>>(MUSIC_DIR_CACHE_SIZE);
|
||||
cachedMusicDirectories = new LRUCache<>(MUSIC_DIR_CACHE_SIZE);
|
||||
cachedArtist = new LRUCache<>(MUSIC_DIR_CACHE_SIZE);
|
||||
cachedAlbum = new LRUCache<>(MUSIC_DIR_CACHE_SIZE);
|
||||
cachedUserInfo = new LRUCache<>(MUSIC_DIR_CACHE_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ping(Context context, ProgressListener progressListener) throws Exception
|
||||
public void ping(Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
musicService.ping(context, progressListener);
|
||||
checkSettingsChanged();
|
||||
musicService.ping(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLicenseValid(Context context, ProgressListener progressListener) throws Exception
|
||||
public boolean isLicenseValid(Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
Boolean result = cachedLicenseValid.get();
|
||||
if (result == null)
|
||||
{
|
||||
result = musicService.isLicenseValid(context, progressListener);
|
||||
result = musicService.isLicenseValid(context);
|
||||
cachedLicenseValid.set(result, result ? 30L * 60L : 2L * 60L, TimeUnit.SECONDS);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MusicFolder> getMusicFolders(boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public List<MusicFolder> getMusicFolders(boolean refresh, Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
if (refresh)
|
||||
{
|
||||
cachedMusicFolders.clear();
|
||||
@ -118,16 +117,16 @@ public class CachedMusicService implements MusicService
|
||||
List<MusicFolder> result = cachedMusicFolders.get();
|
||||
if (result == null)
|
||||
{
|
||||
result = musicService.getMusicFolders(refresh, context, progressListener);
|
||||
result = musicService.getMusicFolders(refresh, context);
|
||||
cachedMusicFolders.set(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Indexes getIndexes(String musicFolderId, boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public Indexes getIndexes(String musicFolderId, boolean refresh, Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
if (refresh)
|
||||
{
|
||||
cachedIndexes.clear();
|
||||
@ -137,16 +136,16 @@ public class CachedMusicService implements MusicService
|
||||
Indexes result = cachedIndexes.get();
|
||||
if (result == null)
|
||||
{
|
||||
result = musicService.getIndexes(musicFolderId, refresh, context, progressListener);
|
||||
result = musicService.getIndexes(musicFolderId, refresh, context);
|
||||
cachedIndexes.set(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Indexes getArtists(boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public Indexes getArtists(boolean refresh, Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
if (refresh)
|
||||
{
|
||||
cachedArtists.clear();
|
||||
@ -154,24 +153,24 @@ public class CachedMusicService implements MusicService
|
||||
Indexes result = cachedArtists.get();
|
||||
if (result == null)
|
||||
{
|
||||
result = musicService.getArtists(refresh, context, progressListener);
|
||||
result = musicService.getArtists(refresh, context);
|
||||
cachedArtists.set(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getMusicDirectory(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getMusicDirectory(String id, String name, boolean refresh, Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
TimeLimitedCache<MusicDirectory> cache = refresh ? null : cachedMusicDirectories.get(id);
|
||||
|
||||
MusicDirectory dir = cache == null ? null : cache.get();
|
||||
|
||||
if (dir == null)
|
||||
{
|
||||
dir = musicService.getMusicDirectory(id, name, refresh, context, progressListener);
|
||||
cache = new TimeLimitedCache<MusicDirectory>(Util.getDirectoryCacheTime(context), TimeUnit.SECONDS);
|
||||
dir = musicService.getMusicDirectory(id, name, refresh, context);
|
||||
cache = new TimeLimitedCache<>(Util.getDirectoryCacheTime(context), TimeUnit.SECONDS);
|
||||
cache.set(dir);
|
||||
cachedMusicDirectories.put(id, cache);
|
||||
}
|
||||
@ -179,15 +178,15 @@ public class CachedMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getArtist(String id, String name, boolean refresh, Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
TimeLimitedCache<MusicDirectory> cache = refresh ? null : cachedArtist.get(id);
|
||||
MusicDirectory dir = cache == null ? null : cache.get();
|
||||
if (dir == null)
|
||||
{
|
||||
dir = musicService.getArtist(id, name, refresh, context, progressListener);
|
||||
cache = new TimeLimitedCache<MusicDirectory>(Util.getDirectoryCacheTime(context), TimeUnit.SECONDS);
|
||||
dir = musicService.getArtist(id, name, refresh, context);
|
||||
cache = new TimeLimitedCache<>(Util.getDirectoryCacheTime(context), TimeUnit.SECONDS);
|
||||
cache.set(dir);
|
||||
cachedArtist.put(id, cache);
|
||||
}
|
||||
@ -195,15 +194,15 @@ public class CachedMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getAlbum(String id, String name, boolean refresh, Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
TimeLimitedCache<MusicDirectory> cache = refresh ? null : cachedAlbum.get(id);
|
||||
MusicDirectory dir = cache == null ? null : cache.get();
|
||||
if (dir == null)
|
||||
{
|
||||
dir = musicService.getAlbum(id, name, refresh, context, progressListener);
|
||||
cache = new TimeLimitedCache<MusicDirectory>(Util.getDirectoryCacheTime(context), TimeUnit.SECONDS);
|
||||
dir = musicService.getAlbum(id, name, refresh, context);
|
||||
cache = new TimeLimitedCache<>(Util.getDirectoryCacheTime(context), TimeUnit.SECONDS);
|
||||
cache.set(dir);
|
||||
cachedAlbum.put(id, cache);
|
||||
}
|
||||
@ -211,113 +210,113 @@ public class CachedMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResult search(SearchCriteria criteria, Context context, ProgressListener progressListener) throws Exception
|
||||
public SearchResult search(SearchCriteria criteria, Context context) throws Exception
|
||||
{
|
||||
return musicService.search(criteria, context, progressListener);
|
||||
return musicService.search(criteria, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getPlaylist(String id, String name, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getPlaylist(String id, String name, Context context) throws Exception
|
||||
{
|
||||
return musicService.getPlaylist(id, name, context, progressListener);
|
||||
return musicService.getPlaylist(id, name, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PodcastsChannel> getPodcastsChannels(boolean refresh, Context context, ProgressListener progressListener) throws Exception {
|
||||
checkSettingsChanged(context);
|
||||
public List<PodcastsChannel> getPodcastsChannels(boolean refresh, Context context) throws Exception {
|
||||
checkSettingsChanged();
|
||||
List<PodcastsChannel> result = refresh ? null : cachedPodcastsChannels.get();
|
||||
if (result == null)
|
||||
{
|
||||
result = musicService.getPodcastsChannels(refresh, context, progressListener);
|
||||
result = musicService.getPodcastsChannels(refresh, context);
|
||||
cachedPodcastsChannels.set(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getPodcastEpisodes(String podcastChannelId, Context context, ProgressListener progressListener) throws Exception {
|
||||
return musicService.getPodcastEpisodes(podcastChannelId,context,progressListener);
|
||||
public MusicDirectory getPodcastEpisodes(String podcastChannelId, Context context) throws Exception {
|
||||
return musicService.getPodcastEpisodes(podcastChannelId,context);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<Playlist> getPlaylists(boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public List<Playlist> getPlaylists(boolean refresh, Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
List<Playlist> result = refresh ? null : cachedPlaylists.get();
|
||||
if (result == null)
|
||||
{
|
||||
result = musicService.getPlaylists(refresh, context, progressListener);
|
||||
result = musicService.getPlaylists(refresh, context);
|
||||
cachedPlaylists.set(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPlaylist(String id, String name, List<MusicDirectory.Entry> entries, Context context, ProgressListener progressListener) throws Exception
|
||||
public void createPlaylist(String id, String name, List<MusicDirectory.Entry> entries, Context context) throws Exception
|
||||
{
|
||||
cachedPlaylists.clear();
|
||||
musicService.createPlaylist(id, name, entries, context, progressListener);
|
||||
musicService.createPlaylist(id, name, entries, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePlaylist(String id, Context context, ProgressListener progressListener) throws Exception
|
||||
public void deletePlaylist(String id, Context context) throws Exception
|
||||
{
|
||||
musicService.deletePlaylist(id, context, progressListener);
|
||||
musicService.deletePlaylist(id, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePlaylist(String id, String name, String comment, boolean pub, Context context, ProgressListener progressListener) throws Exception
|
||||
public void updatePlaylist(String id, String name, String comment, boolean pub, Context context) throws Exception
|
||||
{
|
||||
musicService.updatePlaylist(id, name, comment, pub, context, progressListener);
|
||||
musicService.updatePlaylist(id, name, comment, pub, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lyrics getLyrics(String artist, String title, Context context, ProgressListener progressListener) throws Exception
|
||||
public Lyrics getLyrics(String artist, String title, Context context) throws Exception
|
||||
{
|
||||
return musicService.getLyrics(artist, title, context, progressListener);
|
||||
return musicService.getLyrics(artist, title, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrobble(String id, boolean submission, Context context, ProgressListener progressListener) throws Exception
|
||||
public void scrobble(String id, boolean submission, Context context) throws Exception
|
||||
{
|
||||
musicService.scrobble(id, submission, context, progressListener);
|
||||
musicService.scrobble(id, submission, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getAlbumList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getAlbumList(String type, int size, int offset, Context context) throws Exception
|
||||
{
|
||||
return musicService.getAlbumList(type, size, offset, context, progressListener);
|
||||
return musicService.getAlbumList(type, size, offset, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getAlbumList2(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getAlbumList2(String type, int size, int offset, Context context) throws Exception
|
||||
{
|
||||
return musicService.getAlbumList2(type, size, offset, context, progressListener);
|
||||
return musicService.getAlbumList2(type, size, offset, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getRandomSongs(int size, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getRandomSongs(int size, Context context) throws Exception
|
||||
{
|
||||
return musicService.getRandomSongs(size, context, progressListener);
|
||||
return musicService.getRandomSongs(size, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResult getStarred(Context context, ProgressListener progressListener) throws Exception
|
||||
public SearchResult getStarred(Context context) throws Exception
|
||||
{
|
||||
return musicService.getStarred(context, progressListener);
|
||||
return musicService.getStarred(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResult getStarred2(Context context, ProgressListener progressListener) throws Exception
|
||||
public SearchResult getStarred2(Context context) throws Exception
|
||||
{
|
||||
return musicService.getStarred2(context, progressListener);
|
||||
return musicService.getStarred2(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, boolean saveToFile, boolean highQuality, ProgressListener progressListener) throws Exception
|
||||
public Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, boolean saveToFile, boolean highQuality) throws Exception
|
||||
{
|
||||
return musicService.getCoverArt(context, entry, size, saveToFile, highQuality, progressListener);
|
||||
return musicService.getCoverArt(context, entry, size, saveToFile, highQuality);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -333,42 +332,42 @@ public class CachedMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context) throws Exception
|
||||
{
|
||||
return musicService.updateJukeboxPlaylist(ids, context, progressListener);
|
||||
return musicService.updateJukeboxPlaylist(ids, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus skipJukebox(int index, int offsetSeconds, Context context) throws Exception
|
||||
{
|
||||
return musicService.skipJukebox(index, offsetSeconds, context, progressListener);
|
||||
return musicService.skipJukebox(index, offsetSeconds, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus stopJukebox(Context context) throws Exception
|
||||
{
|
||||
return musicService.stopJukebox(context, progressListener);
|
||||
return musicService.stopJukebox(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus startJukebox(Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus startJukebox(Context context) throws Exception
|
||||
{
|
||||
return musicService.startJukebox(context, progressListener);
|
||||
return musicService.startJukebox(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus getJukeboxStatus(Context context) throws Exception
|
||||
{
|
||||
return musicService.getJukeboxStatus(context, progressListener);
|
||||
return musicService.getJukeboxStatus(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus setJukeboxGain(float gain, Context context) throws Exception
|
||||
{
|
||||
return musicService.setJukeboxGain(gain, context, progressListener);
|
||||
return musicService.setJukeboxGain(gain, context);
|
||||
}
|
||||
|
||||
private void checkSettingsChanged(Context context)
|
||||
private void checkSettingsChanged()
|
||||
{
|
||||
String newUrl = activeServerProvider.getValue().getRestUrl(null);
|
||||
if (!Util.equals(newUrl, restUrl))
|
||||
@ -387,27 +386,27 @@ public class CachedMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public void star(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception
|
||||
public void star(String id, String albumId, String artistId, Context context) throws Exception
|
||||
{
|
||||
musicService.star(id, albumId, artistId, context, progressListener);
|
||||
musicService.star(id, albumId, artistId, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unstar(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception
|
||||
public void unstar(String id, String albumId, String artistId, Context context) throws Exception
|
||||
{
|
||||
musicService.unstar(id, albumId, artistId, context, progressListener);
|
||||
musicService.unstar(id, albumId, artistId, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRating(String id, int rating, Context context, ProgressListener progressListener) throws Exception
|
||||
public void setRating(String id, int rating, Context context) throws Exception
|
||||
{
|
||||
musicService.setRating(id, rating, context, progressListener);
|
||||
musicService.setRating(id, rating, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Genre> getGenres(boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public List<Genre> getGenres(boolean refresh, Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
if (refresh)
|
||||
{
|
||||
cachedGenres.clear();
|
||||
@ -416,7 +415,7 @@ public class CachedMusicService implements MusicService
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
result = musicService.getGenres(refresh, context, progressListener);
|
||||
result = musicService.getGenres(refresh, context);
|
||||
cachedGenres.set(result);
|
||||
}
|
||||
|
||||
@ -433,59 +432,59 @@ public class CachedMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context) throws Exception
|
||||
{
|
||||
return musicService.getSongsByGenre(genre, count, offset, context, progressListener);
|
||||
return musicService.getSongsByGenre(genre, count, offset, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Share> getShares(boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public List<Share> getShares(boolean refresh, Context context) throws Exception
|
||||
{
|
||||
return musicService.getShares(refresh, context, progressListener);
|
||||
return musicService.getShares(refresh, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatMessage> getChatMessages(Long since, Context context, ProgressListener progressListener) throws Exception
|
||||
public List<ChatMessage> getChatMessages(Long since, Context context) throws Exception
|
||||
{
|
||||
return musicService.getChatMessages(since, context, progressListener);
|
||||
return musicService.getChatMessages(since, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChatMessage(String message, Context context, ProgressListener progressListener) throws Exception
|
||||
public void addChatMessage(String message, Context context) throws Exception
|
||||
{
|
||||
musicService.addChatMessage(message, context, progressListener);
|
||||
musicService.addChatMessage(message, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bookmark> getBookmarks(Context context, ProgressListener progressListener) throws Exception
|
||||
public List<Bookmark> getBookmarks(Context context) throws Exception
|
||||
{
|
||||
return musicService.getBookmarks(context, progressListener);
|
||||
return musicService.getBookmarks(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBookmark(String id, Context context, ProgressListener progressListener) throws Exception
|
||||
public void deleteBookmark(String id, Context context) throws Exception
|
||||
{
|
||||
musicService.deleteBookmark(id, context, progressListener);
|
||||
musicService.deleteBookmark(id, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createBookmark(String id, int position, Context context, ProgressListener progressListener) throws Exception
|
||||
public void createBookmark(String id, int position, Context context) throws Exception
|
||||
{
|
||||
musicService.createBookmark(id, position, context, progressListener);
|
||||
musicService.createBookmark(id, position, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getVideos(boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getVideos(boolean refresh, Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
TimeLimitedCache<MusicDirectory> cache = refresh ? null : cachedMusicDirectories.get(Constants.INTENT_EXTRA_NAME_VIDEOS);
|
||||
|
||||
MusicDirectory dir = cache == null ? null : cache.get();
|
||||
|
||||
if (dir == null)
|
||||
{
|
||||
dir = musicService.getVideos(refresh, context, progressListener);
|
||||
cache = new TimeLimitedCache<MusicDirectory>(Util.getDirectoryCacheTime(context), TimeUnit.SECONDS);
|
||||
dir = musicService.getVideos(refresh, context);
|
||||
cache = new TimeLimitedCache<>(Util.getDirectoryCacheTime(context), TimeUnit.SECONDS);
|
||||
cache.set(dir);
|
||||
cachedMusicDirectories.put(Constants.INTENT_EXTRA_NAME_VIDEOS, cache);
|
||||
}
|
||||
@ -494,9 +493,9 @@ public class CachedMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserInfo getUser(String username, Context context, ProgressListener progressListener) throws Exception
|
||||
public UserInfo getUser(String username, Context context) throws Exception
|
||||
{
|
||||
checkSettingsChanged(context);
|
||||
checkSettingsChanged();
|
||||
|
||||
TimeLimitedCache<UserInfo> cache = cachedUserInfo.get(username);
|
||||
|
||||
@ -504,8 +503,8 @@ public class CachedMusicService implements MusicService
|
||||
|
||||
if (userInfo == null)
|
||||
{
|
||||
userInfo = musicService.getUser(username, context, progressListener);
|
||||
cache = new TimeLimitedCache<UserInfo>(Util.getDirectoryCacheTime(context), TimeUnit.SECONDS);
|
||||
userInfo = musicService.getUser(username, context);
|
||||
cache = new TimeLimitedCache<>(Util.getDirectoryCacheTime(context), TimeUnit.SECONDS);
|
||||
cache.set(userInfo);
|
||||
cachedUserInfo.put(username, cache);
|
||||
}
|
||||
@ -514,27 +513,26 @@ public class CachedMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Share> createShare(List<String> ids, String description, Long expires, Context context, ProgressListener progressListener) throws Exception
|
||||
public List<Share> createShare(List<String> ids, String description, Long expires, Context context) throws Exception
|
||||
{
|
||||
return musicService.createShare(ids, description, expires, context, progressListener);
|
||||
return musicService.createShare(ids, description, expires, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteShare(String id, Context context, ProgressListener progressListener) throws Exception
|
||||
public void deleteShare(String id, Context context) throws Exception
|
||||
{
|
||||
musicService.deleteShare(id, context, progressListener);
|
||||
musicService.deleteShare(id, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateShare(String id, String description, Long expires, Context context, ProgressListener progressListener) throws Exception
|
||||
public void updateShare(String id, String description, Long expires, Context context) throws Exception
|
||||
{
|
||||
musicService.updateShare(id, description, expires, context, progressListener);
|
||||
musicService.updateShare(id, description, expires, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap getAvatar(Context context, String username, int size, boolean saveToFile, boolean highQuality, ProgressListener progressListener) throws Exception
|
||||
public Bitmap getAvatar(Context context, String username, int size, boolean saveToFile, boolean highQuality) throws Exception
|
||||
{
|
||||
return musicService.getAvatar(context, username, size, saveToFile, highQuality, progressListener);
|
||||
return musicService.getAvatar(context, username, size, saveToFile, highQuality);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public class DownloadFile
|
||||
private volatile boolean saveWhenDone;
|
||||
private volatile boolean completeWhenDone;
|
||||
|
||||
private Lazy<Downloader> downloader = inject(Downloader.class);
|
||||
private final Lazy<Downloader> downloader = inject(Downloader.class);
|
||||
|
||||
public DownloadFile(Context context, MusicDirectory.Entry song, boolean save)
|
||||
{
|
||||
@ -456,13 +456,13 @@ public class DownloadFile
|
||||
return String.format("DownloadTask (%s)", song);
|
||||
}
|
||||
|
||||
private void downloadAndSaveCoverArt(MusicService musicService) throws Exception
|
||||
private void downloadAndSaveCoverArt(MusicService musicService)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!TextUtils.isEmpty(song.getCoverArt())) {
|
||||
int size = Util.getMinDisplayMetric(context);
|
||||
musicService.getCoverArt(context, song, size, true, true, null);
|
||||
musicService.getCoverArt(context, song, size, true, true);
|
||||
}
|
||||
}
|
||||
catch (Exception x)
|
||||
|
@ -67,13 +67,13 @@ public class JukeboxMediaPlayer
|
||||
private JukeboxStatus jukeboxStatus;
|
||||
private float gain = 0.5f;
|
||||
private VolumeToast volumeToast;
|
||||
private AtomicBoolean running = new AtomicBoolean();
|
||||
private final AtomicBoolean running = new AtomicBoolean();
|
||||
private Thread serviceThread;
|
||||
private boolean enabled = false;
|
||||
private Context context;
|
||||
private final Context context;
|
||||
|
||||
// TODO: These create circular references, try to refactor
|
||||
private Lazy<MediaPlayerControllerImpl> mediaPlayerControllerLazy = inject(MediaPlayerControllerImpl.class);
|
||||
private final Lazy<MediaPlayerControllerImpl> mediaPlayerControllerLazy = inject(MediaPlayerControllerImpl.class);
|
||||
private final Downloader downloader;
|
||||
|
||||
// TODO: Report warning if queue fills up.
|
||||
@ -397,7 +397,7 @@ public class JukeboxMediaPlayer
|
||||
@Override
|
||||
JukeboxStatus execute() throws Exception
|
||||
{
|
||||
return getMusicService().getJukeboxStatus(context, null);
|
||||
return getMusicService().getJukeboxStatus(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,7 +413,7 @@ public class JukeboxMediaPlayer
|
||||
@Override
|
||||
JukeboxStatus execute() throws Exception
|
||||
{
|
||||
return getMusicService().updateJukeboxPlaylist(ids, context, null);
|
||||
return getMusicService().updateJukeboxPlaylist(ids, context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -431,7 +431,7 @@ public class JukeboxMediaPlayer
|
||||
@Override
|
||||
JukeboxStatus execute() throws Exception
|
||||
{
|
||||
return getMusicService().skipJukebox(index, offsetSeconds, context, null);
|
||||
return getMusicService().skipJukebox(index, offsetSeconds, context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -440,7 +440,7 @@ public class JukeboxMediaPlayer
|
||||
@Override
|
||||
JukeboxStatus execute() throws Exception
|
||||
{
|
||||
return getMusicService().stopJukebox(context, null);
|
||||
return getMusicService().stopJukebox(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -449,7 +449,7 @@ public class JukeboxMediaPlayer
|
||||
@Override
|
||||
JukeboxStatus execute() throws Exception
|
||||
{
|
||||
return getMusicService().startJukebox(context, null);
|
||||
return getMusicService().startJukebox(context);
|
||||
}
|
||||
}
|
||||
|
||||
@ -466,7 +466,7 @@ public class JukeboxMediaPlayer
|
||||
@Override
|
||||
JukeboxStatus execute() throws Exception
|
||||
{
|
||||
return getMusicService().setJukeboxGain(gain, context, null);
|
||||
return getMusicService().setJukeboxGain(gain, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,6 @@ import android.content.Intent;
|
||||
import timber.log.Timber;
|
||||
|
||||
import org.koin.java.KoinJavaComponent;
|
||||
import org.moire.ultrasonic.audiofx.EqualizerController;
|
||||
import org.moire.ultrasonic.audiofx.VisualizerController;
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
||||
import org.moire.ultrasonic.domain.MusicDirectory;
|
||||
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
|
||||
@ -60,9 +58,10 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
|
||||
private boolean showVisualization;
|
||||
private boolean autoPlayStart;
|
||||
|
||||
private Context context;
|
||||
private Lazy<JukeboxMediaPlayer> jukeboxMediaPlayer = inject(JukeboxMediaPlayer.class);
|
||||
private Lazy<ActiveServerProvider> activeServerProvider = inject(ActiveServerProvider.class);
|
||||
private final Context context;
|
||||
private final Lazy<JukeboxMediaPlayer> jukeboxMediaPlayer = inject(JukeboxMediaPlayer.class);
|
||||
private final Lazy<ActiveServerProvider> activeServerProvider = inject(ActiveServerProvider.class);
|
||||
|
||||
private final DownloadQueueSerializer downloadQueueSerializer;
|
||||
private final ExternalStorageMonitor externalStorageMonitor;
|
||||
private final Downloader downloader;
|
||||
@ -522,7 +521,7 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
|
||||
try
|
||||
{
|
||||
String username = activeServerProvider.getValue().getActiveServer().getUserName();
|
||||
UserInfo user = MusicServiceFactory.getMusicService(context).getUser(username, context, null);
|
||||
UserInfo user = MusicServiceFactory.getMusicService(context).getUser(username, context);
|
||||
return user.getJukeboxRole();
|
||||
}
|
||||
catch (Exception e)
|
||||
@ -595,7 +594,7 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
|
||||
{
|
||||
try
|
||||
{
|
||||
MusicServiceFactory.getMusicService(context).setRating(song.getId(), rating, context, null);
|
||||
MusicServiceFactory.getMusicService(context).setRating(song.getId(), rating, context);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -541,7 +541,7 @@ public class MediaPlayerService extends Service
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(MediaPlayerService.this);
|
||||
try
|
||||
{
|
||||
musicService.deleteBookmark(song.getId(), MediaPlayerService.this, null);
|
||||
musicService.deleteBookmark(song.getId(), MediaPlayerService.this);
|
||||
}
|
||||
catch (Exception ignored)
|
||||
{
|
||||
|
@ -36,7 +36,6 @@ import org.moire.ultrasonic.domain.SearchResult;
|
||||
import org.moire.ultrasonic.domain.Share;
|
||||
import org.moire.ultrasonic.domain.UserInfo;
|
||||
import org.moire.ultrasonic.util.CancellableTask;
|
||||
import org.moire.ultrasonic.util.ProgressListener;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
@ -49,61 +48,61 @@ import kotlin.Pair;
|
||||
public interface MusicService
|
||||
{
|
||||
|
||||
void ping(Context context, ProgressListener progressListener) throws Exception;
|
||||
void ping(Context context) throws Exception;
|
||||
|
||||
boolean isLicenseValid(Context context, ProgressListener progressListener) throws Exception;
|
||||
boolean isLicenseValid(Context context) throws Exception;
|
||||
|
||||
List<Genre> getGenres(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
List<Genre> getGenres(boolean refresh, Context context) throws Exception;
|
||||
|
||||
void star(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception;
|
||||
void star(String id, String albumId, String artistId, Context context) throws Exception;
|
||||
|
||||
void unstar(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception;
|
||||
void unstar(String id, String albumId, String artistId, Context context) throws Exception;
|
||||
|
||||
void setRating(String id, int rating, Context context, ProgressListener progressListener) throws Exception;
|
||||
void setRating(String id, int rating, Context context) throws Exception;
|
||||
|
||||
List<MusicFolder> getMusicFolders(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
List<MusicFolder> getMusicFolders(boolean refresh, Context context) throws Exception;
|
||||
|
||||
Indexes getIndexes(String musicFolderId, boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
Indexes getIndexes(String musicFolderId, boolean refresh, Context context) throws Exception;
|
||||
|
||||
Indexes getArtists(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
Indexes getArtists(boolean refresh, Context context) throws Exception;
|
||||
|
||||
MusicDirectory getMusicDirectory(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
MusicDirectory getMusicDirectory(String id, String name, boolean refresh, Context context) throws Exception;
|
||||
|
||||
MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
MusicDirectory getArtist(String id, String name, boolean refresh, Context context) throws Exception;
|
||||
|
||||
MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
MusicDirectory getAlbum(String id, String name, boolean refresh, Context context) throws Exception;
|
||||
|
||||
SearchResult search(SearchCriteria criteria, Context context, ProgressListener progressListener) throws Exception;
|
||||
SearchResult search(SearchCriteria criteria, Context context) throws Exception;
|
||||
|
||||
MusicDirectory getPlaylist(String id, String name, Context context, ProgressListener progressListener) throws Exception;
|
||||
MusicDirectory getPlaylist(String id, String name, Context context) throws Exception;
|
||||
|
||||
List<PodcastsChannel> getPodcastsChannels(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
List<PodcastsChannel> getPodcastsChannels(boolean refresh, Context context) throws Exception;
|
||||
|
||||
List<Playlist> getPlaylists(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
List<Playlist> getPlaylists(boolean refresh, Context context) throws Exception;
|
||||
|
||||
void createPlaylist(String id, String name, List<MusicDirectory.Entry> entries, Context context, ProgressListener progressListener) throws Exception;
|
||||
void createPlaylist(String id, String name, List<MusicDirectory.Entry> entries, Context context) throws Exception;
|
||||
|
||||
void deletePlaylist(String id, Context context, ProgressListener progressListener) throws Exception;
|
||||
void deletePlaylist(String id, Context context) throws Exception;
|
||||
|
||||
void updatePlaylist(String id, String name, String comment, boolean pub, Context context, ProgressListener progressListener) throws Exception;
|
||||
void updatePlaylist(String id, String name, String comment, boolean pub, Context context) throws Exception;
|
||||
|
||||
Lyrics getLyrics(String artist, String title, Context context, ProgressListener progressListener) throws Exception;
|
||||
Lyrics getLyrics(String artist, String title, Context context) throws Exception;
|
||||
|
||||
void scrobble(String id, boolean submission, Context context, ProgressListener progressListener) throws Exception;
|
||||
void scrobble(String id, boolean submission, Context context) throws Exception;
|
||||
|
||||
MusicDirectory getAlbumList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception;
|
||||
MusicDirectory getAlbumList(String type, int size, int offset, Context context) throws Exception;
|
||||
|
||||
MusicDirectory getAlbumList2(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception;
|
||||
MusicDirectory getAlbumList2(String type, int size, int offset, Context context) throws Exception;
|
||||
|
||||
MusicDirectory getRandomSongs(int size, Context context, ProgressListener progressListener) throws Exception;
|
||||
MusicDirectory getRandomSongs(int size, Context context) throws Exception;
|
||||
|
||||
MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception;
|
||||
MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context) throws Exception;
|
||||
|
||||
SearchResult getStarred(Context context, ProgressListener progressListener) throws Exception;
|
||||
SearchResult getStarred(Context context) throws Exception;
|
||||
|
||||
SearchResult getStarred2(Context context, ProgressListener progressListener) throws Exception;
|
||||
SearchResult getStarred2(Context context) throws Exception;
|
||||
|
||||
Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, boolean saveToFile, boolean highQuality, ProgressListener progressListener) throws Exception;
|
||||
Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, boolean saveToFile, boolean highQuality) throws Exception;
|
||||
|
||||
/**
|
||||
* Return response {@link InputStream} and a {@link Boolean} that indicates if this response is
|
||||
@ -113,41 +112,41 @@ public interface MusicService
|
||||
|
||||
@Deprecated String getVideoUrl(Context context, String id, boolean useFlash) throws Exception;
|
||||
|
||||
JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception;
|
||||
JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context) throws Exception;
|
||||
|
||||
JukeboxStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception;
|
||||
JukeboxStatus skipJukebox(int index, int offsetSeconds, Context context) throws Exception;
|
||||
|
||||
JukeboxStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception;
|
||||
JukeboxStatus stopJukebox(Context context) throws Exception;
|
||||
|
||||
JukeboxStatus startJukebox(Context context, ProgressListener progressListener) throws Exception;
|
||||
JukeboxStatus startJukebox(Context context) throws Exception;
|
||||
|
||||
JukeboxStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception;
|
||||
JukeboxStatus getJukeboxStatus(Context context) throws Exception;
|
||||
|
||||
JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception;
|
||||
JukeboxStatus setJukeboxGain(float gain, Context context) throws Exception;
|
||||
|
||||
List<Share> getShares(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
List<Share> getShares(boolean refresh, Context context) throws Exception;
|
||||
|
||||
List<ChatMessage> getChatMessages(Long since, Context context, ProgressListener progressListener) throws Exception;
|
||||
List<ChatMessage> getChatMessages(Long since, Context context) throws Exception;
|
||||
|
||||
void addChatMessage(String message, Context context, ProgressListener progressListener) throws Exception;
|
||||
void addChatMessage(String message, Context context) throws Exception;
|
||||
|
||||
List<Bookmark> getBookmarks(Context context, ProgressListener progressListener) throws Exception;
|
||||
List<Bookmark> getBookmarks(Context context) throws Exception;
|
||||
|
||||
void deleteBookmark(String id, Context context, ProgressListener progressListener) throws Exception;
|
||||
void deleteBookmark(String id, Context context) throws Exception;
|
||||
|
||||
void createBookmark(String id, int position, Context context, ProgressListener progressListener) throws Exception;
|
||||
void createBookmark(String id, int position, Context context) throws Exception;
|
||||
|
||||
MusicDirectory getVideos(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
|
||||
MusicDirectory getVideos(boolean refresh, Context context) throws Exception;
|
||||
|
||||
UserInfo getUser(String username, Context context, ProgressListener progressListener) throws Exception;
|
||||
UserInfo getUser(String username, Context context) throws Exception;
|
||||
|
||||
List<Share> createShare(List<String> ids, String description, Long expires, Context context, ProgressListener progressListener) throws Exception;
|
||||
List<Share> createShare(List<String> ids, String description, Long expires, Context context) throws Exception;
|
||||
|
||||
void deleteShare(String id, Context context, ProgressListener progressListener) throws Exception;
|
||||
void deleteShare(String id, Context context) throws Exception;
|
||||
|
||||
void updateShare(String id, String description, Long expires, Context context, ProgressListener progressListener) throws Exception;
|
||||
void updateShare(String id, String description, Long expires, Context context) throws Exception;
|
||||
|
||||
Bitmap getAvatar(Context context, String username, int size, boolean saveToFile, boolean highQuality, ProgressListener progressListener) throws Exception;
|
||||
Bitmap getAvatar(Context context, String username, int size, boolean saveToFile, boolean highQuality) throws Exception;
|
||||
|
||||
MusicDirectory getPodcastEpisodes(String podcastChannelId, Context context, ProgressListener progressListener) throws Exception;
|
||||
MusicDirectory getPodcastEpisodes(String podcastChannelId, Context context) throws Exception;
|
||||
}
|
@ -76,12 +76,12 @@ import static org.koin.java.KoinJavaComponent.inject;
|
||||
public class OfflineMusicService implements MusicService
|
||||
{
|
||||
private static final Pattern COMPILE = Pattern.compile(" ");
|
||||
private Lazy<ActiveServerProvider> activeServerProvider = inject(ActiveServerProvider.class);
|
||||
private final Lazy<ActiveServerProvider> activeServerProvider = inject(ActiveServerProvider.class);
|
||||
|
||||
@Override
|
||||
public Indexes getIndexes(String musicFolderId, boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public Indexes getIndexes(String musicFolderId, boolean refresh, Context context)
|
||||
{
|
||||
List<Artist> artists = new ArrayList<Artist>();
|
||||
List<Artist> artists = new ArrayList<>();
|
||||
File root = FileUtil.getMusicDirectory(context);
|
||||
for (File file : FileUtil.listFiles(root))
|
||||
{
|
||||
@ -144,13 +144,13 @@ public class OfflineMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getMusicDirectory(String id, String artistName, boolean refresh, Context context, ProgressListener progressListener)
|
||||
public MusicDirectory getMusicDirectory(String id, String artistName, boolean refresh, Context context)
|
||||
{
|
||||
File dir = new File(id);
|
||||
MusicDirectory result = new MusicDirectory();
|
||||
result.setName(dir.getName());
|
||||
|
||||
Collection<String> names = new HashSet<String>();
|
||||
Collection<String> names = new HashSet<>();
|
||||
|
||||
for (File file : FileUtil.listMediaFiles(dir))
|
||||
{
|
||||
@ -335,7 +335,7 @@ public class OfflineMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap getAvatar(Context context, String username, int size, boolean saveToFile, boolean highQuality, ProgressListener progressListener)
|
||||
public Bitmap getAvatar(Context context, String username, int size, boolean saveToFile, boolean highQuality)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -349,7 +349,7 @@ public class OfflineMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, boolean saveToFile, boolean highQuality, ProgressListener progressListener)
|
||||
public Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, boolean saveToFile, boolean highQuality)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -363,11 +363,11 @@ public class OfflineMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResult search(SearchCriteria criteria, Context context, ProgressListener progressListener)
|
||||
public SearchResult search(SearchCriteria criteria, Context context)
|
||||
{
|
||||
List<Artist> artists = new ArrayList<Artist>();
|
||||
List<MusicDirectory.Entry> albums = new ArrayList<MusicDirectory.Entry>();
|
||||
List<MusicDirectory.Entry> songs = new ArrayList<MusicDirectory.Entry>();
|
||||
List<Artist> artists = new ArrayList<>();
|
||||
List<MusicDirectory.Entry> albums = new ArrayList<>();
|
||||
List<MusicDirectory.Entry> songs = new ArrayList<>();
|
||||
File root = FileUtil.getMusicDirectory(context);
|
||||
int closeness;
|
||||
|
||||
@ -507,7 +507,7 @@ public class OfflineMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Playlist> getPlaylists(boolean refresh, Context context, ProgressListener progressListener)
|
||||
public List<Playlist> getPlaylists(boolean refresh, Context context)
|
||||
{
|
||||
List<Playlist> playlists = new ArrayList<Playlist>();
|
||||
File root = FileUtil.getPlaylistDirectory(context);
|
||||
@ -564,7 +564,7 @@ public class OfflineMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getPlaylist(String id, String name, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getPlaylist(String id, String name, Context context) throws Exception
|
||||
{
|
||||
Reader reader = null;
|
||||
BufferedReader buffer = null;
|
||||
@ -606,7 +606,7 @@ public class OfflineMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPlaylist(String id, String name, List<MusicDirectory.Entry> entries, Context context, ProgressListener progressListener) throws Exception
|
||||
public void createPlaylist(String id, String name, List<MusicDirectory.Entry> entries, Context context) throws Exception
|
||||
{
|
||||
File playlistFile = FileUtil.getPlaylistFile(context, activeServerProvider.getValue().getActiveServer().getName(), name);
|
||||
FileWriter fw = new FileWriter(playlistFile);
|
||||
@ -639,10 +639,10 @@ public class OfflineMusicService implements MusicService
|
||||
|
||||
|
||||
@Override
|
||||
public MusicDirectory getRandomSongs(int size, Context context, ProgressListener progressListener)
|
||||
public MusicDirectory getRandomSongs(int size, Context context)
|
||||
{
|
||||
File root = FileUtil.getMusicDirectory(context);
|
||||
List<File> children = new LinkedList<File>();
|
||||
List<File> children = new LinkedList<>();
|
||||
listFilesRecursively(root, children);
|
||||
MusicDirectory result = new MusicDirectory();
|
||||
|
||||
@ -677,138 +677,138 @@ public class OfflineMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePlaylist(String id, Context context, ProgressListener progressListener) throws Exception
|
||||
public void deletePlaylist(String id, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Playlists not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updatePlaylist(String id, String name, String comment, boolean pub, Context context, ProgressListener progressListener) throws Exception
|
||||
public void updatePlaylist(String id, String name, String comment, boolean pub, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Updating playlist not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lyrics getLyrics(String artist, String title, Context context, ProgressListener progressListener) throws Exception
|
||||
public Lyrics getLyrics(String artist, String title, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Lyrics not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scrobble(String id, boolean submission, Context context, ProgressListener progressListener) throws Exception
|
||||
public void scrobble(String id, boolean submission, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Scrobbling not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getAlbumList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getAlbumList(String type, int size, int offset, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Album lists not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Jukebox not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus skipJukebox(int index, int offsetSeconds, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Jukebox not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus stopJukebox(Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Jukebox not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus startJukebox(Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus startJukebox(Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Jukebox not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus getJukeboxStatus(Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Jukebox not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception
|
||||
public JukeboxStatus setJukeboxGain(float gain, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Jukebox not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResult getStarred(Context context, ProgressListener progressListener) throws Exception
|
||||
public SearchResult getStarred(Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Starred not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception
|
||||
public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Getting Songs By Genre not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Genre> getGenres(boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public List<Genre> getGenres(boolean refresh, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Getting Genres not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserInfo getUser(String username, Context context, ProgressListener progressListener) throws Exception
|
||||
public UserInfo getUser(String username, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Getting user info not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Share> createShare(List<String> ids, String description, Long expires, Context context, ProgressListener progressListener) throws Exception
|
||||
public List<Share> createShare(List<String> ids, String description, Long expires, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Creating shares not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Share> getShares(boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public List<Share> getShares(boolean refresh, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Getting shares not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteShare(String id, Context context, ProgressListener progressListener) throws Exception
|
||||
public void deleteShare(String id, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Deleting shares not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateShare(String id, String description, Long expires, Context context, ProgressListener progressListener) throws Exception
|
||||
public void updateShare(String id, String description, Long expires, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Updating shares not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void star(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception
|
||||
public void star(String id, String albumId, String artistId, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Star not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unstar(String id, String albumId, String artistId, Context context, ProgressListener progressListener) throws Exception
|
||||
public void unstar(String id, String albumId, String artistId, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("UnStar not available in offline mode");
|
||||
}
|
||||
@Override
|
||||
public List<MusicFolder> getMusicFolders(boolean refresh, Context context, ProgressListener progressListener) throws Exception
|
||||
public List<MusicFolder> getMusicFolders(boolean refresh, Context context) throws Exception
|
||||
{
|
||||
throw new OfflineException("Music folders not available in offline mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getAlbumList2(String type, int size, int offset, Context context, ProgressListener progressListener) {
|
||||
public MusicDirectory getAlbumList2(String type, int size, int offset, Context context) {
|
||||
Timber.w("OfflineMusicService.getAlbumList2 was called but it isn't available");
|
||||
return null;
|
||||
}
|
||||
@ -820,73 +820,73 @@ public class OfflineMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ChatMessage> getChatMessages(Long since, Context context, ProgressListener progressListener) {
|
||||
public List<ChatMessage> getChatMessages(Long since, Context context) {
|
||||
Timber.w("OfflineMusicService.getChatMessages was called but it isn't available");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChatMessage(String message, Context context, ProgressListener progressListener) {
|
||||
public void addChatMessage(String message, Context context) {
|
||||
Timber.w("OfflineMusicService.addChatMessage was called but it isn't available");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Bookmark> getBookmarks(Context context, ProgressListener progressListener) {
|
||||
public List<Bookmark> getBookmarks(Context context) {
|
||||
Timber.w("OfflineMusicService.getBookmarks was called but it isn't available");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteBookmark(String id, Context context, ProgressListener progressListener) {
|
||||
public void deleteBookmark(String id, Context context) {
|
||||
Timber.w("OfflineMusicService.deleteBookmark was called but it isn't available");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createBookmark(String id, int position, Context context, ProgressListener progressListener) {
|
||||
public void createBookmark(String id, int position, Context context) {
|
||||
Timber.w("OfflineMusicService.createBookmark was called but it isn't available");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getVideos(boolean refresh, Context context, ProgressListener progressListener) {
|
||||
public MusicDirectory getVideos(boolean refresh, Context context) {
|
||||
Timber.w("OfflineMusicService.getVideos was called but it isn't available");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchResult getStarred2(Context context, ProgressListener progressListener) {
|
||||
public SearchResult getStarred2(Context context) {
|
||||
Timber.w("OfflineMusicService.getStarred2 was called but it isn't available");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ping(Context context, ProgressListener progressListener) {
|
||||
public void ping(Context context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLicenseValid(Context context, ProgressListener progressListener) {
|
||||
public boolean isLicenseValid(Context context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Indexes getArtists(boolean refresh, Context context, ProgressListener progressListener) {
|
||||
public Indexes getArtists(boolean refresh, Context context) {
|
||||
Timber.w("OfflineMusicService.getArtists was called but it isn't available");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) {
|
||||
public MusicDirectory getArtist(String id, String name, boolean refresh, Context context) {
|
||||
Timber.w("OfflineMusicService.getArtist was called but it isn't available");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) {
|
||||
public MusicDirectory getAlbum(String id, String name, boolean refresh, Context context) {
|
||||
Timber.w("OfflineMusicService.getAlbum was called but it isn't available");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MusicDirectory getPodcastEpisodes(String podcastChannelId, Context context, ProgressListener progressListener) {
|
||||
public MusicDirectory getPodcastEpisodes(String podcastChannelId, Context context) {
|
||||
Timber.w("OfflineMusicService.getPodcastEpisodes was called but it isn't available");
|
||||
return null;
|
||||
}
|
||||
@ -898,12 +898,12 @@ public class OfflineMusicService implements MusicService
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRating(String id, int rating, Context context, ProgressListener progressListener) {
|
||||
public void setRating(String id, int rating, Context context) {
|
||||
Timber.w("OfflineMusicService.setRating was called but it isn't available");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PodcastsChannel> getPodcastsChannels(boolean refresh, Context context, ProgressListener progressListener) {
|
||||
public List<PodcastsChannel> getPodcastsChannels(boolean refresh, Context context) {
|
||||
Timber.w("OfflineMusicService.getPodcastsChannels was called but it isn't available");
|
||||
return null;
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import android.content.Context;
|
||||
import timber.log.Timber;
|
||||
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
||||
import org.moire.ultrasonic.util.Util;
|
||||
|
||||
/**
|
||||
* Scrobbles played songs to Last.fm.
|
||||
@ -19,32 +18,18 @@ public class Scrobbler
|
||||
|
||||
public void scrobble(final Context context, final DownloadFile song, final boolean submission)
|
||||
{
|
||||
if (song == null || !ActiveServerProvider.Companion.isScrobblingEnabled(context))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (song == null || !ActiveServerProvider.Companion.isScrobblingEnabled(context)) return;
|
||||
|
||||
final String id = song.getSong().getId();
|
||||
if (id == null) return;
|
||||
|
||||
// Avoid duplicate registrations.
|
||||
if (submission && id.equals(lastSubmission))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (submission && id.equals(lastSubmission)) return;
|
||||
|
||||
if (!submission && id.equals(lastNowPlaying))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!submission && id.equals(lastNowPlaying)) return;
|
||||
|
||||
if (submission)
|
||||
{
|
||||
lastSubmission = id;
|
||||
}
|
||||
else
|
||||
{
|
||||
lastNowPlaying = id;
|
||||
}
|
||||
if (submission) lastSubmission = id;
|
||||
else lastNowPlaying = id;
|
||||
|
||||
new Thread(String.format("Scrobble %s", song))
|
||||
{
|
||||
@ -54,7 +39,7 @@ public class Scrobbler
|
||||
MusicService service = MusicServiceFactory.getMusicService(context);
|
||||
try
|
||||
{
|
||||
service.scrobble(id, submission, context, null);
|
||||
service.scrobble(id, submission, context);
|
||||
Timber.i("Scrobbled '%s' for %s", submission ? "submission" : "now playing", song);
|
||||
}
|
||||
catch (Exception x)
|
||||
|
@ -8,14 +8,14 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
* @author Sindre Mehus
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class TabActivityBackgroundTask<T> extends BackgroundTask<T>
|
||||
public abstract class FragmentBackgroundTask<T> extends BackgroundTask<T>
|
||||
{
|
||||
private final boolean changeProgress;
|
||||
private final SwipeRefreshLayout swipe;
|
||||
private final CancellationToken cancel;
|
||||
|
||||
public TabActivityBackgroundTask(Activity activity, boolean changeProgress,
|
||||
SwipeRefreshLayout swipe, CancellationToken cancel)
|
||||
public FragmentBackgroundTask(Activity activity, boolean changeProgress,
|
||||
SwipeRefreshLayout swipe, CancellationToken cancel)
|
||||
{
|
||||
super(activity);
|
||||
this.changeProgress = changeProgress;
|
@ -19,7 +19,6 @@
|
||||
package org.moire.ultrasonic.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@ -30,6 +29,9 @@ import timber.log.Timber;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.content.res.ResourcesCompat;
|
||||
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.domain.MusicDirectory;
|
||||
import org.moire.ultrasonic.service.MusicService;
|
||||
@ -38,8 +40,6 @@ import org.moire.ultrasonic.service.MusicServiceFactory;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.SortedSet;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@ -58,9 +58,9 @@ public class LegacyImageLoader implements Runnable, ImageLoader {
|
||||
private final int imageSizeLarge;
|
||||
private Bitmap largeUnknownImage;
|
||||
private Bitmap unknownAvatarImage;
|
||||
private Context context;
|
||||
private final Context context;
|
||||
private Collection<Thread> threads;
|
||||
private AtomicBoolean running = new AtomicBoolean();
|
||||
private final AtomicBoolean running = new AtomicBoolean();
|
||||
private int concurrency;
|
||||
|
||||
public LegacyImageLoader(
|
||||
@ -71,8 +71,7 @@ public class LegacyImageLoader implements Runnable, ImageLoader {
|
||||
this.concurrency = concurrency;
|
||||
queue = new LinkedBlockingQueue<>(1000);
|
||||
|
||||
Resources resources = context.getResources();
|
||||
Drawable drawable = resources.getDrawable(R.drawable.unknown_album);
|
||||
Drawable drawable = ResourcesCompat.getDrawable(context.getResources(), R.drawable.unknown_album, null);
|
||||
|
||||
// Determine the density-dependent image sizes.
|
||||
if (drawable != null) {
|
||||
@ -120,7 +119,7 @@ public class LegacyImageLoader implements Runnable, ImageLoader {
|
||||
}
|
||||
|
||||
private void createLargeUnknownImage(Context context) {
|
||||
Drawable drawable = context.getResources().getDrawable(R.drawable.unknown_album);
|
||||
Drawable drawable = ResourcesCompat.getDrawable(context.getResources(), R.drawable.unknown_album, null);
|
||||
Timber.i("createLargeUnknownImage");
|
||||
|
||||
if (drawable != null) {
|
||||
@ -129,8 +128,7 @@ public class LegacyImageLoader implements Runnable, ImageLoader {
|
||||
}
|
||||
|
||||
private void createUnknownAvatarImage(Context context) {
|
||||
Resources res = context.getResources();
|
||||
Drawable contact = res.getDrawable(R.drawable.ic_contact_picture);
|
||||
Drawable contact = ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_contact_picture, null);
|
||||
unknownAvatarImage = Util.createBitmapFromDrawable(contact);
|
||||
}
|
||||
|
||||
@ -424,8 +422,8 @@ public class LegacyImageLoader implements Runnable, ImageLoader {
|
||||
MusicService musicService = MusicServiceFactory.getMusicService(view.getContext());
|
||||
final boolean isAvatar = this.username != null && this.entry == null;
|
||||
final Bitmap bitmap = this.entry != null ?
|
||||
musicService.getCoverArt(view.getContext(), entry, size, saveToFile, highQuality, null) :
|
||||
musicService.getAvatar(view.getContext(), username, size, saveToFile, highQuality, null);
|
||||
musicService.getCoverArt(view.getContext(), entry, size, saveToFile, highQuality) :
|
||||
musicService.getAvatar(view.getContext(), username, size, saveToFile, highQuality);
|
||||
|
||||
if (bitmap == null) {
|
||||
Timber.d("Found empty album art.");
|
||||
|
@ -32,16 +32,25 @@ import static androidx.core.content.PermissionChecker.PERMISSION_DENIED;
|
||||
*/
|
||||
public class PermissionUtil {
|
||||
|
||||
private final Context context;
|
||||
private Context activityContext;
|
||||
private Context applicationContext;
|
||||
|
||||
public PermissionUtil(Context context) {
|
||||
this.context = context;
|
||||
applicationContext = context;
|
||||
}
|
||||
|
||||
public interface PermissionRequestFinishedCallback {
|
||||
void onPermissionRequestFinished(boolean hasPermission);
|
||||
}
|
||||
|
||||
public void ForegroundApplicationStarted(Context context) {
|
||||
this.activityContext = context;
|
||||
}
|
||||
|
||||
public void ForegroundApplicationStopped() {
|
||||
activityContext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function can be used to handle file access permission failures.
|
||||
*
|
||||
@ -51,26 +60,30 @@ public class PermissionUtil {
|
||||
* @param callback callback function to execute after the permission request is finished
|
||||
*/
|
||||
public void handlePermissionFailed(final PermissionRequestFinishedCallback callback) {
|
||||
// TODO: Test with ApplicationContext
|
||||
String currentCachePath = Util.getPreferences(context).getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, FileUtil.getDefaultMusicDirectory(context).getPath());
|
||||
String defaultCachePath = FileUtil.getDefaultMusicDirectory(context).getPath();
|
||||
String currentCachePath = Util.getPreferences(applicationContext).getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, FileUtil.getDefaultMusicDirectory(applicationContext).getPath());
|
||||
String defaultCachePath = FileUtil.getDefaultMusicDirectory(applicationContext).getPath();
|
||||
|
||||
// Ultrasonic can do nothing about this error when the Music Directory is already set to the default.
|
||||
if (currentCachePath.compareTo(defaultCachePath) == 0) return;
|
||||
|
||||
if ((PermissionChecker.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_DENIED) ||
|
||||
(PermissionChecker.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) == PERMISSION_DENIED)) {
|
||||
if ((PermissionChecker.checkSelfPermission(applicationContext, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_DENIED) ||
|
||||
(PermissionChecker.checkSelfPermission(applicationContext, Manifest.permission.READ_EXTERNAL_STORAGE) == PERMISSION_DENIED)) {
|
||||
// While we request permission, the Music Directory is temporarily reset to its default location
|
||||
setCacheLocation(context, FileUtil.getDefaultMusicDirectory(context).getPath());
|
||||
requestFailedPermission(context, currentCachePath, callback);
|
||||
setCacheLocation(applicationContext, FileUtil.getDefaultMusicDirectory(applicationContext).getPath());
|
||||
// If the application is not running, we can't notify the user
|
||||
if (activityContext == null) return;
|
||||
requestFailedPermission(activityContext, currentCachePath, callback);
|
||||
} else {
|
||||
setCacheLocation(context, FileUtil.getDefaultMusicDirectory(context).getPath());
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showWarning(context, context.getString(R.string.permissions_message_box_title), context.getString(R.string.permissions_access_error), null);
|
||||
}
|
||||
});
|
||||
setCacheLocation(applicationContext, FileUtil.getDefaultMusicDirectory(applicationContext).getPath());
|
||||
// If the application is not running, we can't notify the user
|
||||
if (activityContext != null) {
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showWarning(activityContext, activityContext.getString(R.string.permissions_message_box_title), activityContext.getString(R.string.permissions_access_error), null);
|
||||
}
|
||||
});
|
||||
}
|
||||
callback.onPermissionRequestFinished(false);
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ public class ShufflePlayBuffer
|
||||
private static final int CAPACITY = 50;
|
||||
private static final int REFILL_THRESHOLD = 40;
|
||||
|
||||
private final List<MusicDirectory.Entry> buffer = new ArrayList<MusicDirectory.Entry>();
|
||||
private final List<MusicDirectory.Entry> buffer = new ArrayList<>();
|
||||
private final Context context;
|
||||
private ScheduledExecutorService executorService;
|
||||
private int currentServer;
|
||||
@ -78,7 +78,7 @@ public class ShufflePlayBuffer
|
||||
{
|
||||
clearBufferIfNecessary();
|
||||
|
||||
List<MusicDirectory.Entry> result = new ArrayList<MusicDirectory.Entry>(size);
|
||||
List<MusicDirectory.Entry> result = new ArrayList<>(size);
|
||||
synchronized (buffer)
|
||||
{
|
||||
while (!buffer.isEmpty() && result.size() < size)
|
||||
@ -106,7 +106,7 @@ public class ShufflePlayBuffer
|
||||
{
|
||||
MusicService service = MusicServiceFactory.getMusicService(context);
|
||||
int n = CAPACITY - buffer.size();
|
||||
MusicDirectory songs = service.getRandomSongs(n, context, null);
|
||||
MusicDirectory songs = service.getRandomSongs(n, context);
|
||||
|
||||
synchronized (buffer)
|
||||
{
|
||||
|
@ -23,8 +23,6 @@ import android.graphics.drawable.Drawable;
|
||||
import timber.log.Timber;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import org.moire.ultrasonic.R;
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider;
|
||||
import org.moire.ultrasonic.domain.MusicDirectory;
|
||||
@ -44,10 +42,10 @@ public class AlbumView extends UpdateView
|
||||
private static Drawable starHollowDrawable;
|
||||
private static String theme;
|
||||
|
||||
private Context context;
|
||||
private final Context context;
|
||||
private MusicDirectory.Entry entry;
|
||||
private EntryAdapter.AlbumViewHolder viewHolder;
|
||||
private ImageLoader imageLoader;
|
||||
private final ImageLoader imageLoader;
|
||||
private boolean maximized = false;
|
||||
|
||||
public AlbumView(Context context, ImageLoader imageLoader)
|
||||
@ -75,10 +73,10 @@ public class AlbumView extends UpdateView
|
||||
{
|
||||
LayoutInflater.from(context).inflate(R.layout.album_list_item, this, true);
|
||||
viewHolder = new EntryAdapter.AlbumViewHolder();
|
||||
viewHolder.title = (TextView) findViewById(R.id.album_title);
|
||||
viewHolder.artist = (TextView) findViewById(R.id.album_artist);
|
||||
viewHolder.cover_art = (ImageView) findViewById(R.id.album_coverart);
|
||||
viewHolder.star = (ImageView) findViewById(R.id.album_star);
|
||||
viewHolder.title = findViewById(R.id.album_title);
|
||||
viewHolder.artist = findViewById(R.id.album_artist);
|
||||
viewHolder.cover_art = findViewById(R.id.album_coverart);
|
||||
viewHolder.star = findViewById(R.id.album_star);
|
||||
setTag(viewHolder);
|
||||
}
|
||||
|
||||
@ -164,11 +162,11 @@ public class AlbumView extends UpdateView
|
||||
{
|
||||
if (!isStarred)
|
||||
{
|
||||
musicService.star(!useId3 ? id : null, useId3 ? id : null, null, getContext(), null);
|
||||
musicService.star(!useId3 ? id : null, useId3 ? id : null, null, getContext());
|
||||
}
|
||||
else
|
||||
{
|
||||
musicService.unstar(!useId3 ? id : null, useId3 ? id : null, null, getContext(), null);
|
||||
musicService.unstar(!useId3 ? id : null, useId3 ? id : null, null, getContext());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -15,6 +15,7 @@ import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.view.GravityCompat
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.fragment.app.FragmentContainerView
|
||||
import androidx.navigation.NavController
|
||||
@ -41,13 +42,13 @@ import org.moire.ultrasonic.util.Constants
|
||||
import org.moire.ultrasonic.util.FileUtil
|
||||
import org.moire.ultrasonic.util.NowPlayingEventDistributor
|
||||
import org.moire.ultrasonic.util.NowPlayingEventListener
|
||||
import org.moire.ultrasonic.util.PermissionUtil
|
||||
import org.moire.ultrasonic.util.SubsonicUncaughtExceptionHandler
|
||||
import org.moire.ultrasonic.util.ThemeChangedEventDistributor
|
||||
import org.moire.ultrasonic.util.ThemeChangedEventListener
|
||||
import org.moire.ultrasonic.util.Util
|
||||
import timber.log.Timber
|
||||
|
||||
|
||||
/**
|
||||
* The main Activity of Ultrasonic which loads all other screens as Fragments
|
||||
*/
|
||||
@ -58,10 +59,12 @@ class NavigationActivity : AppCompatActivity() {
|
||||
var podcastsMenuItem: MenuItem? = null
|
||||
var nowPlayingView: FragmentContainerView? = null
|
||||
var nowPlayingHidden = false
|
||||
var navigationView: NavigationView? = null
|
||||
var drawerLayout: DrawerLayout? = null
|
||||
|
||||
private lateinit var appBarConfiguration : AppBarConfiguration
|
||||
private lateinit var nowPlayingEventListener : NowPlayingEventListener
|
||||
private lateinit var themeChangedEventListener : ThemeChangedEventListener
|
||||
private lateinit var appBarConfiguration: AppBarConfiguration
|
||||
private lateinit var nowPlayingEventListener: NowPlayingEventListener
|
||||
private lateinit var themeChangedEventListener: ThemeChangedEventListener
|
||||
|
||||
private val serverSettingsModel: ServerSettingsModel by viewModel()
|
||||
private val lifecycleSupport: MediaPlayerLifecycleSupport by inject()
|
||||
@ -69,12 +72,14 @@ class NavigationActivity : AppCompatActivity() {
|
||||
private val imageLoaderProvider: ImageLoaderProvider by inject()
|
||||
private val nowPlayingEventDistributor: NowPlayingEventDistributor by inject()
|
||||
private val themeChangedEventDistributor: ThemeChangedEventDistributor by inject()
|
||||
private val permissionUtil: PermissionUtil by inject()
|
||||
|
||||
private var infoDialogDisplayed = false
|
||||
private var currentFragmentId: Int = 0
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setUncaughtExceptionHandler()
|
||||
permissionUtil.ForegroundApplicationStarted(this)
|
||||
Util.applyTheme(this)
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -82,6 +87,8 @@ class NavigationActivity : AppCompatActivity() {
|
||||
volumeControlStream = AudioManager.STREAM_MUSIC
|
||||
setContentView(R.layout.navigation_activity)
|
||||
nowPlayingView = findViewById(R.id.now_playing_fragment)
|
||||
navigationView = findViewById(R.id.nav_view)
|
||||
drawerLayout = findViewById(R.id.drawer_layout)
|
||||
|
||||
val toolbar = findViewById<Toolbar>(R.id.toolbar)
|
||||
setSupportActionBar(toolbar)
|
||||
@ -91,13 +98,22 @@ class NavigationActivity : AppCompatActivity() {
|
||||
|
||||
val navController = host.navController
|
||||
|
||||
val drawerLayout : DrawerLayout? = findViewById(R.id.drawer_layout)
|
||||
appBarConfiguration = AppBarConfiguration(
|
||||
setOf(R.id.mainFragment, R.id.selectArtistFragment, R.id.searchFragment,
|
||||
R.id.playlistsFragment, R.id.sharesFragment, R.id.bookmarksFragment,
|
||||
R.id.chatFragment, R.id.podcastFragment, R.id.settingsFragment,
|
||||
R.id.aboutFragment, R.id.playerFragment),
|
||||
drawerLayout)
|
||||
setOf(
|
||||
R.id.mainFragment,
|
||||
R.id.selectArtistFragment,
|
||||
R.id.searchFragment,
|
||||
R.id.playlistsFragment,
|
||||
R.id.sharesFragment,
|
||||
R.id.bookmarksFragment,
|
||||
R.id.chatFragment,
|
||||
R.id.podcastFragment,
|
||||
R.id.settingsFragment,
|
||||
R.id.aboutFragment,
|
||||
R.id.playerFragment
|
||||
),
|
||||
drawerLayout
|
||||
)
|
||||
|
||||
setupActionBar(navController, appBarConfiguration)
|
||||
|
||||
@ -135,8 +151,8 @@ class NavigationActivity : AppCompatActivity() {
|
||||
|
||||
nowPlayingEventListener = object : NowPlayingEventListener {
|
||||
override fun onDismissNowPlaying() {
|
||||
nowPlayingHidden = true;
|
||||
hideNowPlaying();
|
||||
nowPlayingHidden = true
|
||||
hideNowPlaying()
|
||||
}
|
||||
|
||||
override fun onHideNowPlaying() {
|
||||
@ -174,6 +190,7 @@ class NavigationActivity : AppCompatActivity() {
|
||||
nowPlayingEventDistributor.unsubscribe(nowPlayingEventListener)
|
||||
themeChangedEventDistributor.unsubscribe(themeChangedEventListener)
|
||||
imageLoaderProvider.clearImageLoader()
|
||||
permissionUtil.ForegroundApplicationStopped()
|
||||
}
|
||||
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
|
||||
@ -189,12 +206,11 @@ class NavigationActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
private fun setupNavigationMenu(navController: NavController) {
|
||||
val sideNavView = findViewById<NavigationView>(R.id.nav_view)
|
||||
sideNavView?.setupWithNavController(navController)
|
||||
navigationView?.setupWithNavController(navController)
|
||||
|
||||
// The exit menu is handled here manually
|
||||
val exitItem: MenuItem = sideNavView.menu.findItem(R.id.menu_exit)
|
||||
exitItem.setOnMenuItemClickListener { item ->
|
||||
val exitItem: MenuItem? = navigationView?.menu?.findItem(R.id.menu_exit) ?: null
|
||||
exitItem?.setOnMenuItemClickListener { item ->
|
||||
if (item.itemId == R.id.menu_exit) {
|
||||
setResult(Constants.RESULT_CLOSE_ALL)
|
||||
mediaPlayerController.stopJukeboxService()
|
||||
@ -205,19 +221,26 @@ class NavigationActivity : AppCompatActivity() {
|
||||
true
|
||||
}
|
||||
|
||||
chatMenuItem = sideNavView.menu.findItem(R.id.chatFragment)
|
||||
bookmarksMenuItem = sideNavView.menu.findItem(R.id.bookmarksFragment)
|
||||
sharesMenuItem = sideNavView.menu.findItem(R.id.sharesFragment)
|
||||
podcastsMenuItem = sideNavView.menu.findItem(R.id.podcastFragment)
|
||||
chatMenuItem = navigationView?.menu?.findItem(R.id.chatFragment)
|
||||
bookmarksMenuItem = navigationView?.menu?.findItem(R.id.bookmarksFragment)
|
||||
sharesMenuItem = navigationView?.menu?.findItem(R.id.sharesFragment)
|
||||
podcastsMenuItem = navigationView?.menu?.findItem(R.id.podcastFragment)
|
||||
}
|
||||
|
||||
private fun setupActionBar(navController: NavController, appBarConfig: AppBarConfiguration) {
|
||||
setupActionBarWithNavController(navController, appBarConfig)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (drawerLayout?.isDrawerVisible(GravityCompat.START) == true) {
|
||||
this.drawerLayout?.closeDrawer(GravityCompat.START)
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
val retValue = super.onCreateOptionsMenu(menu)
|
||||
val navigationView = findViewById<NavigationView>(R.id.nav_view)
|
||||
if (navigationView == null) {
|
||||
menuInflater.inflate(R.menu.navigation, menu)
|
||||
return true
|
||||
@ -226,22 +249,21 @@ class NavigationActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
return item.onNavDestinationSelected(findNavController(R.id.nav_host_fragment))
|
||||
|| super.onOptionsItemSelected(item)
|
||||
return item.onNavDestinationSelected(findNavController(R.id.nav_host_fragment)) ||
|
||||
super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
return findNavController(R.id.nav_host_fragment).navigateUp(appBarConfiguration)
|
||||
}
|
||||
|
||||
// TODO: Test if this works with external Intents
|
||||
// TODO Test if this works with external Intents
|
||||
// android.intent.action.SEARCH and android.media.action.MEDIA_PLAY_FROM_SEARCH calls here
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
if (intent == null) return;
|
||||
if (intent == null) return
|
||||
|
||||
if (intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_SHOW_PLAYER, false))
|
||||
{
|
||||
if (intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_SHOW_PLAYER, false)) {
|
||||
findNavController(R.id.nav_host_fragment).navigate(R.id.playerFragment)
|
||||
return
|
||||
}
|
||||
@ -250,7 +272,10 @@ class NavigationActivity : AppCompatActivity() {
|
||||
|
||||
if (query != null) {
|
||||
val autoPlay = intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
|
||||
val suggestions = SearchRecentSuggestions(this, SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE)
|
||||
val suggestions = SearchRecentSuggestions(
|
||||
this,
|
||||
SearchSuggestionProvider.AUTHORITY, SearchSuggestionProvider.MODE
|
||||
)
|
||||
suggestions.saveRecentQuery(query, null)
|
||||
|
||||
val bundle = Bundle()
|
||||
@ -265,7 +290,10 @@ class NavigationActivity : AppCompatActivity() {
|
||||
val preferences = Util.getPreferences(this)
|
||||
if (!preferences.contains(Constants.PREFERENCES_KEY_CACHE_LOCATION)) {
|
||||
val editor = preferences.edit()
|
||||
editor.putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, FileUtil.getDefaultMusicDirectory(this).path)
|
||||
editor.putString(
|
||||
Constants.PREFERENCES_KEY_CACHE_LOCATION,
|
||||
FileUtil.getDefaultMusicDirectory(this).path
|
||||
)
|
||||
editor.apply()
|
||||
}
|
||||
}
|
||||
@ -284,7 +312,7 @@ class NavigationActivity : AppCompatActivity() {
|
||||
.setIcon(android.R.drawable.ic_dialog_info)
|
||||
.setTitle(R.string.main_welcome_title)
|
||||
.setMessage(R.string.main_welcome_text)
|
||||
.setPositiveButton(R.string.common_ok) { dialog, i ->
|
||||
.setPositiveButton(R.string.common_ok) { dialog, _ ->
|
||||
dialog.dismiss()
|
||||
findNavController(R.id.nav_host_fragment).navigate(R.id.settingsFragment)
|
||||
}.show()
|
||||
@ -307,7 +335,7 @@ class NavigationActivity : AppCompatActivity() {
|
||||
|
||||
// The logic for nowPlayingHidden is that the user can dismiss NowPlaying with a gesture,
|
||||
// and when the MediaPlayerService requests that it should be shown, it returns
|
||||
nowPlayingHidden = false;
|
||||
nowPlayingHidden = false
|
||||
// Do not show for Player fragment
|
||||
if (currentFragmentId == R.id.playerFragment) {
|
||||
hideNowPlaying()
|
||||
@ -319,7 +347,6 @@ class NavigationActivity : AppCompatActivity() {
|
||||
if (playerState == PlayerState.PAUSED || playerState == PlayerState.STARTED) {
|
||||
val file: DownloadFile? = mediaPlayerController.currentPlaying
|
||||
if (file != null) {
|
||||
val song = file.song
|
||||
nowPlayingView?.visibility = View.VISIBLE
|
||||
}
|
||||
} else {
|
||||
|
@ -5,9 +5,9 @@ import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.android.viewmodel.dsl.viewModel
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.dsl.module
|
||||
import org.moire.ultrasonic.fragment.ServerSettingsModel
|
||||
import org.moire.ultrasonic.data.AppDatabase
|
||||
import org.moire.ultrasonic.data.MIGRATION_1_2
|
||||
import org.moire.ultrasonic.fragment.ServerSettingsModel
|
||||
import org.moire.ultrasonic.util.Util
|
||||
|
||||
const val SP_NAME = "Default_SP"
|
||||
|
@ -1,10 +1,7 @@
|
||||
package org.moire.ultrasonic.di
|
||||
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.dsl.bind
|
||||
import org.koin.dsl.module
|
||||
import org.moire.ultrasonic.cache.AndroidDirectories
|
||||
import org.moire.ultrasonic.cache.Directories
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||
import org.moire.ultrasonic.subsonic.ImageLoaderProvider
|
||||
import org.moire.ultrasonic.util.NowPlayingEventDistributor
|
||||
|
@ -8,12 +8,12 @@ import org.koin.android.viewmodel.dsl.viewModel
|
||||
import org.koin.core.qualifier.named
|
||||
import org.koin.dsl.module
|
||||
import org.moire.ultrasonic.BuildConfig
|
||||
import org.moire.ultrasonic.fragment.ArtistListModel
|
||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
|
||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIVersions
|
||||
import org.moire.ultrasonic.api.subsonic.SubsonicClientConfiguration
|
||||
import org.moire.ultrasonic.cache.PermanentFileStorage
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||
import org.moire.ultrasonic.fragment.ArtistListModel
|
||||
import org.moire.ultrasonic.log.TimberOkHttpLogger
|
||||
import org.moire.ultrasonic.service.ApiCallResponseChecker
|
||||
import org.moire.ultrasonic.service.CachedMusicService
|
||||
|
@ -85,15 +85,15 @@ class ArtistListModel(
|
||||
try {
|
||||
if (!isOffline && !useId3Tags) {
|
||||
musicFolders.postValue(
|
||||
musicService.getMusicFolders(refresh, context, null)
|
||||
musicService.getMusicFolders(refresh, context)
|
||||
)
|
||||
}
|
||||
|
||||
val musicFolderId = activeServerProvider.getActiveServer().musicFolderId
|
||||
|
||||
val result = if (!isOffline && useId3Tags)
|
||||
musicService.getArtists(refresh, context, null)
|
||||
else musicService.getIndexes(musicFolderId, refresh, context, null)
|
||||
musicService.getArtists(refresh, context)
|
||||
else musicService.getIndexes(musicFolderId, refresh, context)
|
||||
|
||||
val retrievedArtists: MutableList<Artist> =
|
||||
ArrayList(result.shortcuts.size + result.artists.size)
|
||||
|
@ -11,6 +11,8 @@ import androidx.lifecycle.Observer
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.google.android.material.switchmaterial.SwitchMaterial
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import java.net.MalformedURLException
|
||||
import java.net.URL
|
||||
import org.koin.android.ext.android.inject
|
||||
import org.koin.android.viewmodel.ext.android.viewModel
|
||||
import org.moire.ultrasonic.BuildConfig
|
||||
@ -27,10 +29,8 @@ import org.moire.ultrasonic.util.ErrorDialog
|
||||
import org.moire.ultrasonic.util.ModalBackgroundTask
|
||||
import org.moire.ultrasonic.util.Util
|
||||
import timber.log.Timber
|
||||
import java.net.MalformedURLException
|
||||
import java.net.URL
|
||||
|
||||
class EditServerFragment: Fragment() {
|
||||
class EditServerFragment : Fragment() {
|
||||
companion object {
|
||||
const val EDIT_SERVER_INTENT_INDEX = "index"
|
||||
}
|
||||
@ -57,8 +57,11 @@ class EditServerFragment: Fragment() {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.server_edit, container, false)
|
||||
}
|
||||
|
||||
@ -370,4 +373,4 @@ class EditServerFragment: Fragment() {
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,4 +29,4 @@ class FragmentTitle {
|
||||
return (fragment.activity as AppCompatActivity).supportActionBar?.subtitle
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,8 +43,11 @@ class SelectArtistFragment : Fragment() {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.select_artist, container, false)
|
||||
}
|
||||
|
||||
@ -54,14 +57,18 @@ class SelectArtistFragment : Fragment() {
|
||||
artistListModel.refresh(refreshArtistListView!!)
|
||||
}
|
||||
|
||||
val shouldShowHeader = (!ActiveServerProvider.isOffline(this.context) && !Util.getShouldUseId3Tags(this.context))
|
||||
val shouldShowHeader = (
|
||||
!ActiveServerProvider.isOffline(this.context) &&
|
||||
!Util.getShouldUseId3Tags(this.context)
|
||||
)
|
||||
|
||||
val title = arguments?.getString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TITLE)
|
||||
|
||||
if (title == null) {
|
||||
setTitle(
|
||||
this,
|
||||
if (ActiveServerProvider.isOffline(this.context)) R.string.music_library_label_offline
|
||||
if (ActiveServerProvider.isOffline(this.context))
|
||||
R.string.music_library_label_offline
|
||||
else R.string.music_library_label
|
||||
)
|
||||
} else {
|
||||
@ -156,17 +163,83 @@ class SelectArtistFragment : Fragment() {
|
||||
private fun onArtistMenuItemSelected(menuItem: MenuItem, artist: Artist): Boolean {
|
||||
when (menuItem.itemId) {
|
||||
R.id.artist_menu_play_now ->
|
||||
downloadHandler.downloadRecursively(this, artist.id, false, false, true, false, false, false, false, true)
|
||||
downloadHandler.downloadRecursively(
|
||||
this,
|
||||
artist.id,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
)
|
||||
R.id.artist_menu_play_next ->
|
||||
downloadHandler.downloadRecursively(this, artist.id, false, false, true, true, false, true, false, true)
|
||||
downloadHandler.downloadRecursively(
|
||||
this,
|
||||
artist.id,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true
|
||||
)
|
||||
R.id.artist_menu_play_last ->
|
||||
downloadHandler.downloadRecursively(this, artist.id, false, true, false, false, false, false, false, true)
|
||||
downloadHandler.downloadRecursively(
|
||||
this,
|
||||
artist.id,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
)
|
||||
R.id.artist_menu_pin ->
|
||||
downloadHandler.downloadRecursively(this, artist.id, true, true, false, false, false, false, false, true)
|
||||
downloadHandler.downloadRecursively(
|
||||
this,
|
||||
artist.id,
|
||||
true,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
)
|
||||
R.id.artist_menu_unpin ->
|
||||
downloadHandler.downloadRecursively(this, artist.id, false, false, false, false, false, false, true, true)
|
||||
downloadHandler.downloadRecursively(
|
||||
this,
|
||||
artist.id,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true
|
||||
)
|
||||
R.id.artist_menu_download ->
|
||||
downloadHandler.downloadRecursively(this, artist.id, false, false, false, false, true, false, false, true)
|
||||
downloadHandler.downloadRecursively(
|
||||
this,
|
||||
artist.id,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
)
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -189,4 +262,4 @@ class SelectArtistFragment : Fragment() {
|
||||
companion object {
|
||||
private const val MENU_GROUP_MUSIC_FOLDER = 10
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ import org.moire.ultrasonic.service.MediaPlayerController
|
||||
import org.moire.ultrasonic.util.Util
|
||||
import timber.log.Timber
|
||||
|
||||
class ServerSelectorFragment: Fragment() {
|
||||
class ServerSelectorFragment : Fragment() {
|
||||
companion object {
|
||||
const val SERVER_SELECTOR_MANAGE_MODE = "manageMode"
|
||||
}
|
||||
@ -40,8 +40,11 @@ class ServerSelectorFragment: Fragment() {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return inflater.inflate(R.layout.server_selector, container, false)
|
||||
}
|
||||
|
||||
@ -155,4 +158,4 @@ class ServerSelectorFragment: Fragment() {
|
||||
bundle.putInt(EDIT_SERVER_INTENT_INDEX, index)
|
||||
findNavController().navigate(R.id.serverSelectorToEditServer, bundle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ package org.moire.ultrasonic.service
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.text.TextUtils
|
||||
import androidx.annotation.StringRes
|
||||
import java.io.BufferedWriter
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
@ -31,7 +30,6 @@ import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.api.subsonic.ApiNotSupportedException
|
||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
|
||||
import org.moire.ultrasonic.api.subsonic.models.AlbumListType.Companion.fromName
|
||||
@ -63,7 +61,6 @@ import org.moire.ultrasonic.domain.toDomainEntityList
|
||||
import org.moire.ultrasonic.domain.toMusicDirectoryDomainEntity
|
||||
import org.moire.ultrasonic.util.CancellableTask
|
||||
import org.moire.ultrasonic.util.FileUtil
|
||||
import org.moire.ultrasonic.util.ProgressListener
|
||||
import org.moire.ultrasonic.util.Util
|
||||
import timber.log.Timber
|
||||
|
||||
@ -78,16 +75,12 @@ open class RESTMusicService(
|
||||
) : MusicService {
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun ping(context: Context, progressListener: ProgressListener?) {
|
||||
updateProgressListener(progressListener, R.string.service_connecting)
|
||||
|
||||
override fun ping(context: Context) {
|
||||
responseChecker.callWithResponseCheck { api -> api.ping().execute() }
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun isLicenseValid(context: Context, progressListener: ProgressListener?): Boolean {
|
||||
updateProgressListener(progressListener, R.string.service_connecting)
|
||||
|
||||
override fun isLicenseValid(context: Context): Boolean {
|
||||
val response = responseChecker.callWithResponseCheck { api -> api.getLicense().execute() }
|
||||
|
||||
return response.body()!!.license.valid
|
||||
@ -96,8 +89,7 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun getMusicFolders(
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): List<MusicFolder> {
|
||||
val cachedMusicFolders = fileStorage.load(
|
||||
MUSIC_FOLDER_STORAGE_NAME, getMusicFolderListSerializer()
|
||||
@ -105,8 +97,6 @@ open class RESTMusicService(
|
||||
|
||||
if (cachedMusicFolders != null && !refresh) return cachedMusicFolders
|
||||
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getMusicFolders().execute()
|
||||
}
|
||||
@ -121,14 +111,11 @@ open class RESTMusicService(
|
||||
override fun getIndexes(
|
||||
musicFolderId: String?,
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): Indexes {
|
||||
val cachedIndexes = fileStorage.load(INDEXES_STORAGE_NAME, getIndexesSerializer())
|
||||
if (cachedIndexes != null && !refresh) return cachedIndexes
|
||||
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getIndexes(musicFolderId, null).execute()
|
||||
}
|
||||
@ -141,14 +128,11 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun getArtists(
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): Indexes {
|
||||
val cachedArtists = fileStorage.load(ARTISTS_STORAGE_NAME, getIndexesSerializer())
|
||||
if (cachedArtists != null && !refresh) return cachedArtists
|
||||
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getArtists(null).execute()
|
||||
}
|
||||
@ -163,11 +147,8 @@ open class RESTMusicService(
|
||||
id: String?,
|
||||
albumId: String?,
|
||||
artistId: String?,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api -> api.star(id, albumId, artistId).execute() }
|
||||
}
|
||||
|
||||
@ -176,11 +157,8 @@ open class RESTMusicService(
|
||||
id: String?,
|
||||
albumId: String?,
|
||||
artistId: String?,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api -> api.unstar(id, albumId, artistId).execute() }
|
||||
}
|
||||
|
||||
@ -188,11 +166,8 @@ open class RESTMusicService(
|
||||
override fun setRating(
|
||||
id: String,
|
||||
rating: Int,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api -> api.setRating(id, rating).execute() }
|
||||
}
|
||||
|
||||
@ -201,11 +176,8 @@ open class RESTMusicService(
|
||||
id: String,
|
||||
name: String?,
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): MusicDirectory {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getMusicDirectory(id).execute()
|
||||
}
|
||||
@ -218,11 +190,8 @@ open class RESTMusicService(
|
||||
id: String,
|
||||
name: String?,
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): MusicDirectory {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api -> api.getArtist(id).execute() }
|
||||
|
||||
return response.body()!!.artist.toMusicDirectoryDomainEntity()
|
||||
@ -233,11 +202,8 @@ open class RESTMusicService(
|
||||
id: String,
|
||||
name: String?,
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): MusicDirectory {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api -> api.getAlbum(id).execute() }
|
||||
|
||||
return response.body()!!.album.toMusicDirectoryDomainEntity()
|
||||
@ -246,18 +212,17 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun search(
|
||||
criteria: SearchCriteria,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): SearchResult {
|
||||
return try {
|
||||
if (
|
||||
!isOffline(context) &&
|
||||
Util.getShouldUseId3Tags(context)
|
||||
) search3(criteria, progressListener)
|
||||
else search2(criteria, progressListener)
|
||||
) search3(criteria)
|
||||
else search2(criteria)
|
||||
} catch (ignored: ApiNotSupportedException) {
|
||||
// Ensure backward compatibility with REST 1.3.
|
||||
searchOld(criteria, progressListener)
|
||||
searchOld(criteria)
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,11 +231,8 @@ open class RESTMusicService(
|
||||
*/
|
||||
@Throws(Exception::class)
|
||||
private fun searchOld(
|
||||
criteria: SearchCriteria,
|
||||
progressListener: ProgressListener?
|
||||
criteria: SearchCriteria
|
||||
): SearchResult {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.search(null, null, null, criteria.query, criteria.songCount, null, null)
|
||||
.execute()
|
||||
@ -284,12 +246,9 @@ open class RESTMusicService(
|
||||
*/
|
||||
@Throws(Exception::class)
|
||||
private fun search2(
|
||||
criteria: SearchCriteria,
|
||||
progressListener: ProgressListener?
|
||||
criteria: SearchCriteria
|
||||
): SearchResult {
|
||||
requireNotNull(criteria.query) { "Query param is null" }
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.search2(
|
||||
criteria.query, criteria.artistCount, null, criteria.albumCount, null,
|
||||
@ -302,12 +261,9 @@ open class RESTMusicService(
|
||||
|
||||
@Throws(Exception::class)
|
||||
private fun search3(
|
||||
criteria: SearchCriteria,
|
||||
progressListener: ProgressListener?
|
||||
criteria: SearchCriteria
|
||||
): SearchResult {
|
||||
requireNotNull(criteria.query) { "Query param is null" }
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.search3(
|
||||
criteria.query, criteria.artistCount, null, criteria.albumCount, null,
|
||||
@ -322,11 +278,8 @@ open class RESTMusicService(
|
||||
override fun getPlaylist(
|
||||
id: String,
|
||||
name: String?,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): MusicDirectory {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getPlaylist(id).execute()
|
||||
}
|
||||
@ -374,11 +327,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun getPlaylists(
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): List<Playlist> {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getPlaylists(null).execute()
|
||||
}
|
||||
@ -391,8 +341,7 @@ open class RESTMusicService(
|
||||
id: String?,
|
||||
name: String?,
|
||||
entries: List<MusicDirectory.Entry>,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
val pSongIds: MutableList<String> = ArrayList(entries.size)
|
||||
|
||||
@ -401,9 +350,6 @@ open class RESTMusicService(
|
||||
pSongIds.add(id1)
|
||||
}
|
||||
}
|
||||
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api ->
|
||||
api.createPlaylist(id, name, pSongIds.toList()).execute()
|
||||
}
|
||||
@ -412,11 +358,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun deletePlaylist(
|
||||
id: String,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api -> api.deletePlaylist(id).execute() }
|
||||
}
|
||||
|
||||
@ -426,11 +369,8 @@ open class RESTMusicService(
|
||||
name: String?,
|
||||
comment: String?,
|
||||
pub: Boolean,
|
||||
context: Context?,
|
||||
progressListener: ProgressListener?
|
||||
context: Context?
|
||||
) {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api ->
|
||||
api.updatePlaylist(id, name, comment, pub, null, null)
|
||||
.execute()
|
||||
@ -440,11 +380,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun getPodcastsChannels(
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): List<PodcastsChannel> {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getPodcasts(false, null).execute()
|
||||
}
|
||||
@ -455,11 +392,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun getPodcastEpisodes(
|
||||
podcastChannelId: String?,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): MusicDirectory {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getPodcasts(true, podcastChannelId).execute()
|
||||
}
|
||||
@ -485,11 +419,8 @@ open class RESTMusicService(
|
||||
override fun getLyrics(
|
||||
artist: String?,
|
||||
title: String?,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): Lyrics {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getLyrics(artist, title).execute()
|
||||
}
|
||||
@ -501,11 +432,8 @@ open class RESTMusicService(
|
||||
override fun scrobble(
|
||||
id: String,
|
||||
submission: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api ->
|
||||
api.scrobble(id, null, submission).execute()
|
||||
}
|
||||
@ -516,11 +444,8 @@ open class RESTMusicService(
|
||||
type: String,
|
||||
size: Int,
|
||||
offset: Int,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): MusicDirectory {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getAlbumList(fromName(type), size, offset, null, null, null, null)
|
||||
.execute()
|
||||
@ -538,11 +463,8 @@ open class RESTMusicService(
|
||||
type: String,
|
||||
size: Int,
|
||||
offset: Int,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): MusicDirectory {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getAlbumList2(
|
||||
fromName(type),
|
||||
@ -564,11 +486,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun getRandomSongs(
|
||||
size: Int,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): MusicDirectory {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getRandomSongs(
|
||||
size,
|
||||
@ -587,11 +506,8 @@ open class RESTMusicService(
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun getStarred(
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): SearchResult {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getStarred(null).execute()
|
||||
}
|
||||
@ -601,11 +517,8 @@ open class RESTMusicService(
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun getStarred2(
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): SearchResult {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getStarred2(null).execute()
|
||||
}
|
||||
@ -619,8 +532,7 @@ open class RESTMusicService(
|
||||
entry: MusicDirectory.Entry?,
|
||||
size: Int,
|
||||
saveToFile: Boolean,
|
||||
highQuality: Boolean,
|
||||
progressListener: ProgressListener?
|
||||
highQuality: Boolean
|
||||
): Bitmap? {
|
||||
// Synchronize on the entry so that we don't download concurrently for
|
||||
// the same song.
|
||||
@ -744,11 +656,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun updateJukeboxPlaylist(
|
||||
ids: List<String>?,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): JukeboxStatus {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.jukeboxControl(JukeboxAction.SET, null, null, ids, null)
|
||||
.execute()
|
||||
@ -761,11 +670,8 @@ open class RESTMusicService(
|
||||
override fun skipJukebox(
|
||||
index: Int,
|
||||
offsetSeconds: Int,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): JukeboxStatus {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.jukeboxControl(JukeboxAction.SKIP, index, offsetSeconds, null, null)
|
||||
.execute()
|
||||
@ -776,11 +682,8 @@ open class RESTMusicService(
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun stopJukebox(
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): JukeboxStatus {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.jukeboxControl(JukeboxAction.STOP, null, null, null, null)
|
||||
.execute()
|
||||
@ -791,11 +694,8 @@ open class RESTMusicService(
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun startJukebox(
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): JukeboxStatus {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.jukeboxControl(JukeboxAction.START, null, null, null, null)
|
||||
.execute()
|
||||
@ -806,11 +706,8 @@ open class RESTMusicService(
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun getJukeboxStatus(
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): JukeboxStatus {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.jukeboxControl(JukeboxAction.STATUS, null, null, null, null)
|
||||
.execute()
|
||||
@ -822,11 +719,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun setJukeboxGain(
|
||||
gain: Float,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): JukeboxStatus {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.jukeboxControl(JukeboxAction.SET_GAIN, null, null, null, gain)
|
||||
.execute()
|
||||
@ -838,11 +732,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun getShares(
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): List<Share> {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api -> api.getShares().execute() }
|
||||
|
||||
return response.body()!!.shares.toDomainEntitiesList()
|
||||
@ -851,11 +742,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun getGenres(
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): List<Genre> {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api -> api.getGenres().execute() }
|
||||
|
||||
return response.body()!!.genresList.toDomainEntityList()
|
||||
@ -866,11 +754,8 @@ open class RESTMusicService(
|
||||
genre: String,
|
||||
count: Int,
|
||||
offset: Int,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): MusicDirectory {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getSongsByGenre(genre, count, offset, null).execute()
|
||||
}
|
||||
@ -884,11 +769,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun getUser(
|
||||
username: String,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): UserInfo {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getUser(username).execute()
|
||||
}
|
||||
@ -899,11 +781,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun getChatMessages(
|
||||
since: Long?,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): List<ChatMessage> {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.getChatMessages(since).execute()
|
||||
}
|
||||
@ -914,21 +793,15 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun addChatMessage(
|
||||
message: String,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api -> api.addChatMessage(message).execute() }
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun getBookmarks(
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): List<Bookmark> {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api -> api.getBookmarks().execute() }
|
||||
|
||||
return response.body()!!.bookmarkList.toDomainEntitiesList()
|
||||
@ -938,11 +811,8 @@ open class RESTMusicService(
|
||||
override fun createBookmark(
|
||||
id: String,
|
||||
position: Int,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api ->
|
||||
api.createBookmark(id, position.toLong(), null).execute()
|
||||
}
|
||||
@ -951,22 +821,16 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun deleteBookmark(
|
||||
id: String,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api -> api.deleteBookmark(id).execute() }
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun getVideos(
|
||||
refresh: Boolean,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): MusicDirectory {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api -> api.getVideos().execute() }
|
||||
|
||||
val musicDirectory = MusicDirectory()
|
||||
@ -980,11 +844,8 @@ open class RESTMusicService(
|
||||
ids: List<String>,
|
||||
description: String?,
|
||||
expires: Long?,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
): List<Share> {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
val response = responseChecker.callWithResponseCheck { api ->
|
||||
api.createShare(ids, description, expires).execute()
|
||||
}
|
||||
@ -995,11 +856,8 @@ open class RESTMusicService(
|
||||
@Throws(Exception::class)
|
||||
override fun deleteShare(
|
||||
id: String,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api -> api.deleteShare(id).execute() }
|
||||
}
|
||||
|
||||
@ -1008,16 +866,13 @@ open class RESTMusicService(
|
||||
id: String,
|
||||
description: String?,
|
||||
expires: Long?,
|
||||
context: Context,
|
||||
progressListener: ProgressListener?
|
||||
context: Context
|
||||
) {
|
||||
var expiresValue: Long? = expires
|
||||
if (expires != null && expires == 0L) {
|
||||
expiresValue = null
|
||||
}
|
||||
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
|
||||
responseChecker.callWithResponseCheck { api ->
|
||||
api.updateShare(id, description, expiresValue).execute()
|
||||
}
|
||||
@ -1029,8 +884,7 @@ open class RESTMusicService(
|
||||
username: String?,
|
||||
size: Int,
|
||||
saveToFile: Boolean,
|
||||
highQuality: Boolean,
|
||||
progressListener: ProgressListener?
|
||||
highQuality: Boolean
|
||||
): Bitmap? {
|
||||
// Synchronize on the username so that we don't download concurrently for
|
||||
// the same user.
|
||||
@ -1045,7 +899,6 @@ open class RESTMusicService(
|
||||
if (bitmap == null) {
|
||||
var inputStream: InputStream? = null
|
||||
try {
|
||||
updateProgressListener(progressListener, R.string.parser_reading)
|
||||
val response = subsonicAPIClient.getAvatar(username)
|
||||
|
||||
if (response.hasError()) return null
|
||||
@ -1079,13 +932,6 @@ open class RESTMusicService(
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateProgressListener(
|
||||
progressListener: ProgressListener?,
|
||||
@StringRes messageId: Int
|
||||
) {
|
||||
progressListener?.updateProgress(messageId)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val MUSIC_FOLDER_STORAGE_NAME = "music_folder"
|
||||
private const val INDEXES_STORAGE_NAME = "indexes"
|
||||
|
@ -3,6 +3,8 @@ package org.moire.ultrasonic.subsonic
|
||||
import android.app.Activity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import java.util.Collections
|
||||
import java.util.LinkedList
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.data.ActiveServerProvider.Companion.isOffline
|
||||
import org.moire.ultrasonic.domain.MusicDirectory
|
||||
@ -12,7 +14,6 @@ import org.moire.ultrasonic.util.Constants
|
||||
import org.moire.ultrasonic.util.EntryByDiscAndTrackComparator
|
||||
import org.moire.ultrasonic.util.ModalBackgroundTask
|
||||
import org.moire.ultrasonic.util.Util
|
||||
import java.util.*
|
||||
|
||||
class DownloadHandler(
|
||||
val mediaPlayerController: MediaPlayerController,
|
||||
@ -20,14 +21,31 @@ class DownloadHandler(
|
||||
) {
|
||||
private val MAX_SONGS = 500
|
||||
|
||||
fun download(fragment: Fragment, append: Boolean, save: Boolean, autoPlay: Boolean, playNext: Boolean, shuffle: Boolean, songs: List<MusicDirectory.Entry?>) {
|
||||
fun download(
|
||||
fragment: Fragment,
|
||||
append: Boolean,
|
||||
save: Boolean,
|
||||
autoPlay: Boolean,
|
||||
playNext: Boolean,
|
||||
shuffle: Boolean,
|
||||
songs: List<MusicDirectory.Entry?>
|
||||
) {
|
||||
val onValid = Runnable {
|
||||
if (!append && !playNext) {
|
||||
mediaPlayerController.clear()
|
||||
}
|
||||
networkAndStorageChecker.warnIfNetworkOrStorageUnavailable()
|
||||
mediaPlayerController.download(songs, save, autoPlay, playNext, shuffle, false)
|
||||
val playlistName: String? = fragment.arguments?.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME)
|
||||
mediaPlayerController.download(
|
||||
songs,
|
||||
save,
|
||||
autoPlay,
|
||||
playNext,
|
||||
shuffle,
|
||||
false
|
||||
)
|
||||
val playlistName: String? = fragment.arguments?.getString(
|
||||
Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME
|
||||
)
|
||||
if (playlistName != null) {
|
||||
mediaPlayerController.suggestedPlaylistName = playlistName
|
||||
}
|
||||
@ -37,22 +55,93 @@ class DownloadHandler(
|
||||
fragment.findNavController().navigate(R.id.playerFragment)
|
||||
}
|
||||
} else if (save) {
|
||||
Util.toast(fragment.context, fragment.resources.getQuantityString(R.plurals.select_album_n_songs_pinned, songs.size, songs.size))
|
||||
Util.toast(
|
||||
fragment.context,
|
||||
fragment.resources.getQuantityString(
|
||||
R.plurals.select_album_n_songs_pinned,
|
||||
songs.size,
|
||||
songs.size
|
||||
)
|
||||
)
|
||||
} else if (playNext) {
|
||||
Util.toast(fragment.context, fragment.resources.getQuantityString(R.plurals.select_album_n_songs_play_next, songs.size, songs.size))
|
||||
Util.toast(
|
||||
fragment.context,
|
||||
fragment.resources.getQuantityString(
|
||||
R.plurals.select_album_n_songs_play_next,
|
||||
songs.size,
|
||||
songs.size
|
||||
)
|
||||
)
|
||||
} else if (append) {
|
||||
Util.toast(fragment.context, fragment.resources.getQuantityString(R.plurals.select_album_n_songs_added, songs.size, songs.size))
|
||||
Util.toast(
|
||||
fragment.context,
|
||||
fragment.resources.getQuantityString(
|
||||
R.plurals.select_album_n_songs_added,
|
||||
songs.size,
|
||||
songs.size
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
onValid.run()
|
||||
}
|
||||
|
||||
fun downloadPlaylist(fragment: Fragment, id: String, name: String?, save: Boolean, append: Boolean, autoplay: Boolean, shuffle: Boolean, background: Boolean, playNext: Boolean, unpin: Boolean) {
|
||||
downloadRecursively(fragment, id, name, false, false, save, append, autoplay, shuffle, background, playNext, unpin, false)
|
||||
fun downloadPlaylist(
|
||||
fragment: Fragment,
|
||||
id: String,
|
||||
name: String?,
|
||||
save: Boolean,
|
||||
append: Boolean,
|
||||
autoplay: Boolean,
|
||||
shuffle: Boolean,
|
||||
background: Boolean,
|
||||
playNext: Boolean,
|
||||
unpin: Boolean
|
||||
) {
|
||||
downloadRecursively(
|
||||
fragment,
|
||||
id,
|
||||
name,
|
||||
false,
|
||||
false,
|
||||
save,
|
||||
append,
|
||||
autoplay,
|
||||
shuffle,
|
||||
background,
|
||||
playNext,
|
||||
unpin,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
fun downloadShare(fragment: Fragment, id: String, name: String?, save: Boolean, append: Boolean, autoplay: Boolean, shuffle: Boolean, background: Boolean, playNext: Boolean, unpin: Boolean) {
|
||||
downloadRecursively(fragment, id, name, true, false, save, append, autoplay, shuffle, background, playNext, unpin, false)
|
||||
fun downloadShare(
|
||||
fragment: Fragment,
|
||||
id: String,
|
||||
name: String?,
|
||||
save: Boolean,
|
||||
append: Boolean,
|
||||
autoplay: Boolean,
|
||||
shuffle: Boolean,
|
||||
background: Boolean,
|
||||
playNext: Boolean,
|
||||
unpin: Boolean
|
||||
) {
|
||||
downloadRecursively(
|
||||
fragment,
|
||||
id,
|
||||
name,
|
||||
true,
|
||||
false,
|
||||
save,
|
||||
append,
|
||||
autoplay,
|
||||
shuffle,
|
||||
background,
|
||||
playNext,
|
||||
unpin,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
fun downloadRecursively(
|
||||
@ -81,7 +170,8 @@ class DownloadHandler(
|
||||
background = background,
|
||||
playNext = playNext,
|
||||
unpin = unpin,
|
||||
isArtist = isArtist)
|
||||
isArtist = isArtist
|
||||
)
|
||||
}
|
||||
|
||||
fun downloadRecursively(
|
||||
@ -100,7 +190,7 @@ class DownloadHandler(
|
||||
isArtist: Boolean
|
||||
) {
|
||||
val activity = fragment.activity as Activity
|
||||
val task = object: ModalBackgroundTask<List<MusicDirectory.Entry>>(
|
||||
val task = object : ModalBackgroundTask<List<MusicDirectory.Entry>>(
|
||||
activity,
|
||||
false
|
||||
) {
|
||||
@ -115,12 +205,12 @@ class DownloadHandler(
|
||||
} else {
|
||||
if (isDirectory) {
|
||||
root = if (!isOffline(activity) && Util.getShouldUseId3Tags(activity))
|
||||
musicService.getAlbum(id, name, false, activity, null)
|
||||
musicService.getAlbum(id, name, false, activity)
|
||||
else
|
||||
musicService.getMusicDirectory(id, name, false, activity, null)
|
||||
musicService.getMusicDirectory(id, name, false, activity)
|
||||
} else if (isShare) {
|
||||
root = MusicDirectory()
|
||||
val shares = musicService.getShares(true, activity, null)
|
||||
val shares = musicService.getShares(true, activity)
|
||||
for (share in shares) {
|
||||
if (share.id == id) {
|
||||
for (entry in share.getEntries()) {
|
||||
@ -130,7 +220,7 @@ class DownloadHandler(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
root = musicService.getPlaylist(id, name, activity, null)
|
||||
root = musicService.getPlaylist(id, name, activity)
|
||||
}
|
||||
getSongsRecursively(root, songs)
|
||||
}
|
||||
@ -138,7 +228,10 @@ class DownloadHandler(
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
private fun getSongsRecursively(parent: MusicDirectory, songs: MutableList<MusicDirectory.Entry>) {
|
||||
private fun getSongsRecursively(
|
||||
parent: MusicDirectory,
|
||||
songs: MutableList<MusicDirectory.Entry>
|
||||
) {
|
||||
if (songs.size > MAX_SONGS) {
|
||||
return
|
||||
}
|
||||
@ -150,21 +243,32 @@ class DownloadHandler(
|
||||
val musicService = getMusicService(activity)
|
||||
for ((id1, _, _, title) in parent.getChildren(true, false)) {
|
||||
var root: MusicDirectory
|
||||
root = if (!isOffline(activity) && Util.getShouldUseId3Tags(activity)) musicService.getAlbum(id1, title, false, activity, null)
|
||||
else musicService.getMusicDirectory(id1, title, false, activity, null)
|
||||
root = if (
|
||||
!isOffline(activity) &&
|
||||
Util.getShouldUseId3Tags(activity)
|
||||
) musicService.getAlbum(id1, title, false, activity)
|
||||
else musicService.getMusicDirectory(id1, title, false, activity)
|
||||
getSongsRecursively(root, songs)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
private fun getSongsForArtist(id: String, songs: MutableCollection<MusicDirectory.Entry>) {
|
||||
private fun getSongsForArtist(
|
||||
id: String,
|
||||
songs: MutableCollection<MusicDirectory.Entry>
|
||||
) {
|
||||
if (songs.size > MAX_SONGS) {
|
||||
return
|
||||
}
|
||||
val musicService = getMusicService(activity)
|
||||
val artist = musicService.getArtist(id, "", false, activity, null)
|
||||
val artist = musicService.getArtist(id, "", false, activity)
|
||||
for ((id1) in artist.getChildren()) {
|
||||
val albumDirectory = musicService.getAlbum(id1, "", false, activity, null)
|
||||
val albumDirectory = musicService.getAlbum(
|
||||
id1,
|
||||
"",
|
||||
false,
|
||||
activity
|
||||
)
|
||||
for (song in albumDirectory.getChildren()) {
|
||||
if (!song.isVideo) {
|
||||
songs.add(song)
|
||||
@ -186,9 +290,22 @@ class DownloadHandler(
|
||||
if (unpin) {
|
||||
mediaPlayerController.unpin(songs)
|
||||
} else {
|
||||
mediaPlayerController.download(songs, save, autoPlay, playNext, shuffle, false)
|
||||
if (!append && Util.getShouldTransitionOnPlaybackPreference(activity)) {
|
||||
fragment.findNavController().popBackStack(R.id.playerFragment, true)
|
||||
mediaPlayerController.download(
|
||||
songs,
|
||||
save,
|
||||
autoPlay,
|
||||
playNext,
|
||||
shuffle,
|
||||
false
|
||||
)
|
||||
if (
|
||||
!append &&
|
||||
Util.getShouldTransitionOnPlaybackPreference(activity)
|
||||
) {
|
||||
fragment.findNavController().popBackStack(
|
||||
R.id.playerFragment,
|
||||
true
|
||||
)
|
||||
fragment.findNavController().navigate(R.id.playerFragment)
|
||||
}
|
||||
}
|
||||
|
@ -9,13 +9,15 @@ import org.moire.ultrasonic.util.ImageLoader
|
||||
import org.moire.ultrasonic.util.LegacyImageLoader
|
||||
import org.moire.ultrasonic.util.Util
|
||||
|
||||
class ImageLoaderProvider (val context: Context) {
|
||||
class ImageLoaderProvider(val context: Context) {
|
||||
private var imageLoader: ImageLoader? = null
|
||||
|
||||
@Synchronized
|
||||
fun clearImageLoader() {
|
||||
if (imageLoader != null &&
|
||||
imageLoader!!.isRunning) {
|
||||
if (
|
||||
imageLoader != null &&
|
||||
imageLoader!!.isRunning
|
||||
) {
|
||||
imageLoader!!.clear()
|
||||
}
|
||||
imageLoader = null
|
||||
@ -42,4 +44,4 @@ class ImageLoaderProvider (val context: Context) {
|
||||
}
|
||||
return imageLoader!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,4 +13,4 @@ class NetworkAndStorageChecker(val context: Context) {
|
||||
Util.toast(context, R.string.select_album_no_network)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import android.widget.CheckBox
|
||||
import android.widget.EditText
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import java.util.regex.Pattern
|
||||
import org.moire.ultrasonic.R
|
||||
import org.moire.ultrasonic.domain.MusicDirectory
|
||||
import org.moire.ultrasonic.domain.Share
|
||||
@ -16,13 +17,11 @@ import org.moire.ultrasonic.service.MusicServiceFactory.getMusicService
|
||||
import org.moire.ultrasonic.util.BackgroundTask
|
||||
import org.moire.ultrasonic.util.CancellationToken
|
||||
import org.moire.ultrasonic.util.Constants
|
||||
import org.moire.ultrasonic.util.FragmentBackgroundTask
|
||||
import org.moire.ultrasonic.util.ShareDetails
|
||||
import org.moire.ultrasonic.util.TabActivityBackgroundTask
|
||||
import org.moire.ultrasonic.util.TimeSpan
|
||||
import org.moire.ultrasonic.util.TimeSpanPicker
|
||||
import org.moire.ultrasonic.util.Util
|
||||
import java.util.*
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class ShareHandler(val context: Context) {
|
||||
private var shareDescription: EditText? = null
|
||||
@ -32,7 +31,12 @@ class ShareHandler(val context: Context) {
|
||||
private var saveAsDefaultsCheckBox: CheckBox? = null
|
||||
private val pattern = Pattern.compile(":")
|
||||
|
||||
fun createShare(fragment: Fragment, entries: List<MusicDirectory.Entry?>?, swipe: SwipeRefreshLayout?, cancellationToken: CancellationToken) {
|
||||
fun createShare(
|
||||
fragment: Fragment,
|
||||
entries: List<MusicDirectory.Entry?>?,
|
||||
swipe: SwipeRefreshLayout?,
|
||||
cancellationToken: CancellationToken
|
||||
) {
|
||||
val askForDetails = Util.getShouldAskForShareDetails(context)
|
||||
val shareDetails = ShareDetails()
|
||||
shareDetails.Entries = entries
|
||||
@ -40,13 +44,25 @@ class ShareHandler(val context: Context) {
|
||||
showDialog(fragment, shareDetails, swipe, cancellationToken)
|
||||
} else {
|
||||
shareDetails.Description = Util.getDefaultShareDescription(context)
|
||||
shareDetails.Expiration = TimeSpan.getCurrentTime().add(Util.getDefaultShareExpirationInMillis(context)).totalMilliseconds
|
||||
shareDetails.Expiration = TimeSpan.getCurrentTime().add(
|
||||
Util.getDefaultShareExpirationInMillis(context)
|
||||
).totalMilliseconds
|
||||
share(fragment, shareDetails, swipe, cancellationToken)
|
||||
}
|
||||
}
|
||||
|
||||
fun share(fragment: Fragment, shareDetails: ShareDetails, swipe: SwipeRefreshLayout?, cancellationToken: CancellationToken) {
|
||||
val task: BackgroundTask<Share> = object : TabActivityBackgroundTask<Share>(fragment.requireActivity(), true, swipe, cancellationToken) {
|
||||
fun share(
|
||||
fragment: Fragment,
|
||||
shareDetails: ShareDetails,
|
||||
swipe: SwipeRefreshLayout?,
|
||||
cancellationToken: CancellationToken
|
||||
) {
|
||||
val task: BackgroundTask<Share> = object : FragmentBackgroundTask<Share>(
|
||||
fragment.requireActivity(),
|
||||
true,
|
||||
swipe,
|
||||
cancellationToken
|
||||
) {
|
||||
@Throws(Throwable::class)
|
||||
override fun doInBackground(): Share {
|
||||
val ids: MutableList<String?> = ArrayList()
|
||||
@ -62,33 +78,49 @@ class ShareHandler(val context: Context) {
|
||||
if (shareDetails.Expiration != 0L) {
|
||||
timeInMillis = shareDetails.Expiration
|
||||
}
|
||||
val shares = musicService.createShare(ids, shareDetails.Description, timeInMillis, context, this)
|
||||
val shares =
|
||||
musicService.createShare(ids, shareDetails.Description, timeInMillis, context)
|
||||
return shares[0]
|
||||
}
|
||||
|
||||
override fun done(result: Share) {
|
||||
val intent = Intent(Intent.ACTION_SEND)
|
||||
intent.type = "text/plain"
|
||||
intent.putExtra(Intent.EXTRA_TEXT, String.format("%s\n\n%s", Util.getShareGreeting(context), result.url))
|
||||
fragment.activity?.startActivity(Intent.createChooser(intent, context.getResources().getString(R.string.share_via)))
|
||||
intent.putExtra(
|
||||
Intent.EXTRA_TEXT,
|
||||
String.format("%s\n\n%s", Util.getShareGreeting(context), result.url)
|
||||
)
|
||||
fragment.activity?.startActivity(
|
||||
Intent.createChooser(
|
||||
intent,
|
||||
context.getResources().getString(R.string.share_via)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
task.execute()
|
||||
}
|
||||
|
||||
private fun showDialog(fragment: Fragment, shareDetails: ShareDetails, swipe: SwipeRefreshLayout?, cancellationToken: CancellationToken) {
|
||||
private fun showDialog(
|
||||
fragment: Fragment,
|
||||
shareDetails: ShareDetails,
|
||||
swipe: SwipeRefreshLayout?,
|
||||
cancellationToken: CancellationToken
|
||||
) {
|
||||
val layout = LayoutInflater.from(fragment.context).inflate(R.layout.share_details, null)
|
||||
|
||||
if (layout != null) {
|
||||
shareDescription = layout.findViewById<View>(R.id.share_description) as EditText
|
||||
hideDialogCheckBox = layout.findViewById<View>(R.id.hide_dialog) as CheckBox
|
||||
noExpirationCheckBox = layout.findViewById<View>(R.id.timeSpanDisableCheckBox) as CheckBox
|
||||
noExpirationCheckBox = layout.findViewById<View>(
|
||||
R.id.timeSpanDisableCheckBox
|
||||
) as CheckBox
|
||||
saveAsDefaultsCheckBox = layout.findViewById<View>(R.id.save_as_defaults) as CheckBox
|
||||
timeSpanPicker = layout.findViewById<View>(R.id.date_picker) as TimeSpanPicker
|
||||
}
|
||||
val builder = AlertDialog.Builder(fragment.context)
|
||||
builder.setTitle(R.string.share_set_share_options)
|
||||
builder.setPositiveButton(R.string.common_save) { dialog, clickId ->
|
||||
builder.setPositiveButton(R.string.common_save) { _, _ ->
|
||||
if (!noExpirationCheckBox!!.isChecked) {
|
||||
val timeSpan: TimeSpan = timeSpanPicker!!.timeSpan
|
||||
val now = TimeSpan.getCurrentTime()
|
||||
@ -101,18 +133,26 @@ class ShareHandler(val context: Context) {
|
||||
if (saveAsDefaultsCheckBox!!.isChecked) {
|
||||
val timeSpanType: String = timeSpanPicker!!.timeSpanType
|
||||
val timeSpanAmount: Int = timeSpanPicker!!.timeSpanAmount
|
||||
Util.setDefaultShareExpiration(context, if (!noExpirationCheckBox!!.isChecked && timeSpanAmount > 0) String.format("%d:%s", timeSpanAmount, timeSpanType) else "")
|
||||
Util.setDefaultShareExpiration(
|
||||
context,
|
||||
if (!noExpirationCheckBox!!.isChecked && timeSpanAmount > 0)
|
||||
String.format("%d:%s", timeSpanAmount, timeSpanType) else ""
|
||||
)
|
||||
Util.setDefaultShareDescription(context, shareDetails.Description)
|
||||
}
|
||||
share(fragment, shareDetails, swipe, cancellationToken)
|
||||
}
|
||||
builder.setNegativeButton(R.string.common_cancel) { dialog, clickId ->
|
||||
builder.setNegativeButton(R.string.common_cancel) { dialog, _ ->
|
||||
dialog.cancel()
|
||||
}
|
||||
builder.setView(layout)
|
||||
builder.setCancelable(true)
|
||||
timeSpanPicker!!.setTimeSpanDisableText(context.resources.getString(R.string.no_expiration))
|
||||
noExpirationCheckBox!!.setOnCheckedChangeListener { _, b -> timeSpanPicker!!.isEnabled = !b }
|
||||
noExpirationCheckBox!!.setOnCheckedChangeListener {
|
||||
_,
|
||||
b ->
|
||||
timeSpanPicker!!.isEnabled = !b
|
||||
}
|
||||
val defaultDescription = Util.getDefaultShareDescription(context)
|
||||
val timeSpan = Util.getDefaultShareExpiration(context)
|
||||
val split = pattern.split(timeSpan)
|
||||
@ -136,4 +176,4 @@ class ShareHandler(val context: Context) {
|
||||
builder.create()
|
||||
builder.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,4 +18,4 @@ class VideoPlayer(val context: Context) {
|
||||
Util.toast(context, e.message, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,6 @@ class CancellationToken {
|
||||
* Requests that this token be cancelled
|
||||
*/
|
||||
fun cancel() {
|
||||
isCancellationRequested = true;
|
||||
isCancellationRequested = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package org.moire.ultrasonic.util
|
||||
|
||||
class NowPlayingEventDistributor {
|
||||
var eventListenerList: MutableList<NowPlayingEventListener> = listOf<NowPlayingEventListener>().toMutableList()
|
||||
var eventListenerList: MutableList<NowPlayingEventListener> =
|
||||
listOf<NowPlayingEventListener>().toMutableList()
|
||||
|
||||
fun subscribe(listener: NowPlayingEventListener) {
|
||||
eventListenerList.add(listener)
|
||||
@ -12,14 +13,14 @@ class NowPlayingEventDistributor {
|
||||
}
|
||||
|
||||
fun RaiseShowNowPlayingEvent() {
|
||||
eventListenerList.forEach{ listener -> listener.onShowNowPlaying() }
|
||||
eventListenerList.forEach { listener -> listener.onShowNowPlaying() }
|
||||
}
|
||||
|
||||
fun RaiseHideNowPlayingEvent() {
|
||||
eventListenerList.forEach{ listener -> listener.onHideNowPlaying() }
|
||||
eventListenerList.forEach { listener -> listener.onHideNowPlaying() }
|
||||
}
|
||||
|
||||
fun RaiseNowPlayingDismissedEvent() {
|
||||
eventListenerList.forEach{ listener -> listener.onDismissNowPlaying() }
|
||||
eventListenerList.forEach { listener -> listener.onDismissNowPlaying() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,4 +4,4 @@ interface NowPlayingEventListener {
|
||||
fun onDismissNowPlaying()
|
||||
fun onHideNowPlaying()
|
||||
fun onShowNowPlaying()
|
||||
}
|
||||
}
|
||||
|
@ -2,19 +2,20 @@ package org.moire.ultrasonic.util
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import timber.log.Timber
|
||||
import java.io.File
|
||||
import java.io.PrintWriter
|
||||
import timber.log.Timber
|
||||
|
||||
private const val filename = "ultrasonic-stacktrace.txt"
|
||||
|
||||
/**
|
||||
* Logs the stack trace of uncaught exceptions to a file on the SD card.
|
||||
*/
|
||||
class SubsonicUncaughtExceptionHandler (
|
||||
class SubsonicUncaughtExceptionHandler(
|
||||
private val context: Context
|
||||
) : Thread.UncaughtExceptionHandler {
|
||||
private val defaultHandler: Thread.UncaughtExceptionHandler? = Thread.getDefaultUncaughtExceptionHandler()
|
||||
) : Thread.UncaughtExceptionHandler {
|
||||
private val defaultHandler: Thread.UncaughtExceptionHandler? =
|
||||
Thread.getDefaultUncaughtExceptionHandler()
|
||||
|
||||
override fun uncaughtException(thread: Thread, throwable: Throwable) {
|
||||
var file: File? = null
|
||||
@ -24,8 +25,10 @@ class SubsonicUncaughtExceptionHandler (
|
||||
file = File(FileUtil.getUltrasonicDirectory(context), filename)
|
||||
printWriter = PrintWriter(file)
|
||||
val logMessage = String.format(
|
||||
"Android API level: %s\nUltrasonic version name: %s\nUltrasonic version code: %s\n\n",
|
||||
Build.VERSION.SDK_INT, Util.getVersionName(context), Util.getVersionCode(context))
|
||||
"Android API level: %s\nUltrasonic version name: %s\n" +
|
||||
"Ultrasonic version code: %s\n\n",
|
||||
Build.VERSION.SDK_INT, Util.getVersionName(context), Util.getVersionCode(context)
|
||||
)
|
||||
printWriter.println(logMessage)
|
||||
throwable.printStackTrace(printWriter)
|
||||
Timber.e(throwable, "Uncaught Exception! %s", logMessage)
|
||||
@ -37,4 +40,4 @@ class SubsonicUncaughtExceptionHandler (
|
||||
defaultHandler?.uncaughtException(thread, throwable)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package org.moire.ultrasonic.util
|
||||
|
||||
class ThemeChangedEventDistributor {
|
||||
var eventListenerList: MutableList<ThemeChangedEventListener> = listOf<ThemeChangedEventListener>().toMutableList()
|
||||
var eventListenerList: MutableList<ThemeChangedEventListener> =
|
||||
listOf<ThemeChangedEventListener>().toMutableList()
|
||||
|
||||
fun subscribe(listener: ThemeChangedEventListener) {
|
||||
eventListenerList.add(listener)
|
||||
@ -12,6 +13,6 @@ class ThemeChangedEventDistributor {
|
||||
}
|
||||
|
||||
fun RaiseThemeChangedEvent() {
|
||||
eventListenerList.forEach{ listener -> listener.onThemeChanged() }
|
||||
eventListenerList.forEach { listener -> listener.onThemeChanged() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,4 +2,4 @@ package org.moire.ultrasonic.util
|
||||
|
||||
interface ThemeChangedEventListener {
|
||||
fun onThemeChanged()
|
||||
}
|
||||
}
|
||||
|
@ -204,9 +204,9 @@ class SongView(context: Context) : UpdateView(context), Checkable {
|
||||
val musicService = getMusicService(this@SongView.context)
|
||||
try {
|
||||
if (!isStarred) {
|
||||
musicService.star(id, null, null, this@SongView.context, null)
|
||||
musicService.star(id, null, null, this@SongView.context)
|
||||
} else {
|
||||
musicService.unstar(id, null, null, this@SongView.context, null)
|
||||
musicService.unstar(id, null, null, this@SongView.context)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e)
|
||||
|
@ -4,43 +4,48 @@
|
||||
a:layout_height="fill_parent"
|
||||
a:orientation="vertical" >
|
||||
|
||||
<ListView
|
||||
a:id="@+id/chat_entries_list"
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
a:id="@+id/chat_refresh"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="0dip"
|
||||
a:layout_weight="1.0" />
|
||||
a:layout_height="0dp"
|
||||
a:layout_weight="1.0">
|
||||
<ListView
|
||||
a:id="@+id/chat_entries_list"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="0dip"
|
||||
a:layout_weight="1.0" />
|
||||
|
||||
<LinearLayout
|
||||
a:layout_height="4dip"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_marginTop="4dip"
|
||||
a:background="@drawable/drop_shadow" />
|
||||
<LinearLayout
|
||||
a:layout_height="4dip"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_marginTop="4dip"
|
||||
a:background="@drawable/drop_shadow" />
|
||||
|
||||
<LinearLayout
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:orientation="horizontal"
|
||||
a:gravity="bottom" >
|
||||
<LinearLayout
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:orientation="horizontal"
|
||||
a:gravity="bottom" >
|
||||
|
||||
<EditText
|
||||
a:id="@+id/chat_edittext"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="40dip"
|
||||
a:layout_weight="1"
|
||||
a:autoLink="all"
|
||||
a:hint="@string/chat.send_a_message"
|
||||
a:inputType="textEmailAddress|textMultiLine"
|
||||
a:linksClickable="true"
|
||||
a:paddingBottom="10dip"
|
||||
a:paddingTop="10dip" />
|
||||
<EditText
|
||||
a:id="@+id/chat_edittext"
|
||||
a:layout_width="0dip"
|
||||
a:layout_height="40dip"
|
||||
a:layout_weight="1"
|
||||
a:autoLink="all"
|
||||
a:hint="@string/chat.send_a_message"
|
||||
a:inputType="textEmailAddress|textMultiLine"
|
||||
a:linksClickable="true"
|
||||
a:paddingBottom="10dip"
|
||||
a:paddingTop="10dip" />
|
||||
|
||||
<ImageButton
|
||||
a:id="@+id/chat_send"
|
||||
a:layout_width="55dip"
|
||||
a:layout_height="40dip"
|
||||
a:background="@color/transparent"
|
||||
a:src="?attr/chat_send" />
|
||||
|
||||
</LinearLayout>
|
||||
<ImageButton
|
||||
a:id="@+id/chat_send"
|
||||
a:layout_width="55dip"
|
||||
a:layout_height="40dip"
|
||||
a:background="@color/transparent"
|
||||
a:src="?attr/chat_send" />
|
||||
|
||||
</LinearLayout>
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
</LinearLayout>
|
||||
|
@ -3,21 +3,25 @@
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="fill_parent"
|
||||
a:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
a:id="@+id/select_podcasts_empty"
|
||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
a:id="@+id/podcasts_refresh"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:padding="10dip"
|
||||
a:text="@string/podcasts_channels.empty"
|
||||
a:visibility="gone" />
|
||||
|
||||
<ListView
|
||||
a:id="@+id/podcasts_channels_items_list"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="0dip"
|
||||
a:layout_weight="1.0"
|
||||
a:fastScrollEnabled="true"
|
||||
a:textFilterEnabled="true" />
|
||||
a:layout_height="0dp"
|
||||
a:layout_weight="1.0">
|
||||
<TextView
|
||||
a:id="@+id/select_podcasts_empty"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="wrap_content"
|
||||
a:padding="10dip"
|
||||
a:text="@string/podcasts_channels.empty"
|
||||
a:visibility="gone" />
|
||||
|
||||
<ListView
|
||||
a:id="@+id/podcasts_channels_items_list"
|
||||
a:layout_width="fill_parent"
|
||||
a:layout_height="0dip"
|
||||
a:layout_weight="1.0"
|
||||
a:fastScrollEnabled="true"
|
||||
a:textFilterEnabled="true" />
|
||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||
</LinearLayout>
|
Loading…
x
Reference in New Issue
Block a user