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