commit
746afcc638
194 changed files with 5984 additions and 7491 deletions
|
@ -6,7 +6,6 @@ import android.view.View
|
|||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import butterknife.ButterKnife
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.loaders.PlaylistLoader
|
||||
|
@ -24,9 +23,8 @@ class AddToPlaylistDialog : RoundedBottomSheetDialogFragment() {
|
|||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
val layout = inflater.inflate(R.layout.dialog_add_to_playlist, container, false)
|
||||
ButterKnife.bind(this, layout)
|
||||
return layout
|
||||
|
||||
return inflater.inflate(R.layout.dialog_add_to_playlist, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
|
|
@ -6,7 +6,6 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import butterknife.ButterKnife
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||
import code.name.monkey.retromusic.R
|
||||
|
@ -23,9 +22,8 @@ class CreatePlaylistDialog : RoundedBottomSheetDialogFragment() {
|
|||
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
val layout = inflater.inflate(R.layout.dialog_playlist, container, false)
|
||||
ButterKnife.bind(this, layout)
|
||||
return layout
|
||||
|
||||
return inflater.inflate(R.layout.dialog_playlist, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.text.Html
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import butterknife.ButterKnife
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
|
@ -19,9 +18,7 @@ class DeletePlaylistDialog : RoundedBottomSheetDialogFragment() {
|
|||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
val layout = inflater.inflate(R.layout.dialog_remove_from_playlist, container, false)
|
||||
ButterKnife.bind(this, layout)
|
||||
return layout
|
||||
return inflater.inflate(R.layout.dialog_remove_from_playlist, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
|
|
@ -1,100 +0,0 @@
|
|||
package code.name.monkey.retromusic.dialogs;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
|
||||
|
||||
public class DeleteSongsDialog extends RoundedBottomSheetDialogFragment {
|
||||
@BindView(R.id.action_delete)
|
||||
MaterialButton actionDelete;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
@BindView(R.id.action_cancel)
|
||||
MaterialButton actionCancel;
|
||||
|
||||
@NonNull
|
||||
public static DeleteSongsDialog create(Song song) {
|
||||
ArrayList<Song> list = new ArrayList<>();
|
||||
list.add(song);
|
||||
return create(list);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static DeleteSongsDialog create(ArrayList<Song> songs) {
|
||||
DeleteSongsDialog dialog = new DeleteSongsDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelableArrayList("songs", songs);
|
||||
dialog.setArguments(args);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@OnClick({R.id.action_cancel, R.id.action_delete})
|
||||
void actions(View view) {
|
||||
//noinspection ConstantConditions
|
||||
final ArrayList<Song> songs = getArguments().getParcelableArrayList("songs");
|
||||
switch (view.getId()) {
|
||||
case R.id.action_delete:
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
if (songs != null) {
|
||||
MusicUtil.deleteTracks(getActivity(), songs);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
title.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
MaterialUtil.setTint(actionDelete, true);
|
||||
MaterialUtil.setTint(actionCancel, false);
|
||||
|
||||
//noinspection unchecked,ConstantConditions
|
||||
final ArrayList<Song> songs = getArguments().getParcelableArrayList("songs");
|
||||
CharSequence content;
|
||||
if (songs != null) {
|
||||
if (songs.size() > 1) {
|
||||
content = Html.fromHtml(getString(R.string.delete_x_songs, songs.size()));
|
||||
} else {
|
||||
content = Html.fromHtml(getString(R.string.delete_song_x, songs.get(0).getTitle()));
|
||||
}
|
||||
this.title.setText(content);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
View layout = inflater.inflate(R.layout.dialog_delete, container, false);
|
||||
ButterKnife.bind(this, layout);
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
package code.name.monkey.retromusic.dialogs
|
||||
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
|
||||
import kotlinx.android.synthetic.main.dialog_delete.*
|
||||
import java.util.*
|
||||
|
||||
class DeleteSongsDialog : RoundedBottomSheetDialogFragment() {
|
||||
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
title.setTextColor(ThemeStore.textColorPrimary(context!!))
|
||||
MaterialUtil.setTint(actionDelete, true)
|
||||
MaterialUtil.setTint(actionCancel, false)
|
||||
|
||||
//noinspection unchecked,ConstantConditions
|
||||
val songs = arguments!!.getParcelableArrayList<Song>("songs")
|
||||
val content: CharSequence
|
||||
if (songs != null) {
|
||||
content = if (songs.size > 1) {
|
||||
Html.fromHtml(getString(R.string.delete_x_songs, songs.size))
|
||||
} else {
|
||||
Html.fromHtml(getString(R.string.delete_song_x, songs[0].title))
|
||||
}
|
||||
this.title.text = content
|
||||
}
|
||||
actionDelete.setOnClickListener {
|
||||
if (songs != null) {
|
||||
MusicUtil.deleteTracks(activity!!, songs)
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
actionCancel.setOnClickListener { dismiss() }
|
||||
}
|
||||
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.dialog_delete, container, false)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun create(song: Song): DeleteSongsDialog {
|
||||
val list = ArrayList<Song>()
|
||||
list.add(song)
|
||||
return create(list)
|
||||
}
|
||||
|
||||
fun create(songs: ArrayList<Song>): DeleteSongsDialog {
|
||||
val dialog = DeleteSongsDialog()
|
||||
val args = Bundle()
|
||||
args.putParcelableArrayList("songs", songs)
|
||||
dialog.arguments = args
|
||||
return dialog
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,6 @@ import android.text.Html
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import butterknife.ButterKnife
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.model.PlaylistSong
|
||||
|
@ -19,9 +18,8 @@ import java.util.*
|
|||
class RemoveFromPlaylistDialog : RoundedBottomSheetDialogFragment() {
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
val layout = inflater.inflate(R.layout.dialog_remove_from_playlist, container, false)
|
||||
ButterKnife.bind(this, layout)
|
||||
return layout
|
||||
|
||||
return inflater.inflate(R.layout.dialog_remove_from_playlist, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import butterknife.ButterKnife
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||
import code.name.monkey.retromusic.R
|
||||
|
@ -17,9 +16,8 @@ class RenamePlaylistDialog : RoundedBottomSheetDialogFragment() {
|
|||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
val layout = inflater.inflate(R.layout.dialog_playlist, container, false)
|
||||
ButterKnife.bind(this, layout)
|
||||
return layout
|
||||
|
||||
return inflater.inflate(R.layout.dialog_playlist, container, false)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
|
|
|
@ -1,193 +0,0 @@
|
|||
package code.name.monkey.retromusic.dialogs;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ClipDrawable;
|
||||
import android.graphics.drawable.LayerDrawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.CountDownTimer;
|
||||
import android.os.SystemClock;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.material.button.MaterialButton;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.service.MusicService;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
|
||||
|
||||
import static code.name.monkey.retromusic.Constants.ACTION_QUIT;
|
||||
|
||||
public class SleepTimerDialog extends RoundedBottomSheetDialogFragment {
|
||||
@BindView(R.id.seek_arc)
|
||||
SeekBar seekArc;
|
||||
|
||||
@BindView(R.id.timer_display)
|
||||
TextView timerDisplay;
|
||||
|
||||
@BindView(R.id.action_set)
|
||||
MaterialButton setButton;
|
||||
|
||||
@BindView(R.id.action_cancel)
|
||||
MaterialButton cancelButton;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
private int seekArcProgress;
|
||||
private TimerUpdater timerUpdater;
|
||||
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
timerUpdater.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
if (makeTimerPendingIntent(PendingIntent.FLAG_NO_CREATE) != null) {
|
||||
timerUpdater.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View layout = inflater.inflate(R.layout.dialog_sleep_timer, container, false);
|
||||
ButterKnife.bind(this, layout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
private void setProgressBarColor(int dark) {
|
||||
LayerDrawable ld = (LayerDrawable) seekArc.getProgressDrawable();
|
||||
ClipDrawable clipDrawable = (ClipDrawable) ld.findDrawableByLayerId(android.R.id.progress);
|
||||
clipDrawable.setColorFilter(dark, PorterDuff.Mode.SRC_IN);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
MaterialUtil.setTint(setButton, true);
|
||||
MaterialUtil.setTint(cancelButton, false);
|
||||
|
||||
title.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
timerDisplay.setTextColor(ThemeStore.textColorSecondary(getContext()));
|
||||
|
||||
timerUpdater = new TimerUpdater();
|
||||
|
||||
seekArcProgress = PreferenceUtil.getInstance().getLastSleepTimerValue();
|
||||
updateTimeDisplayTime();
|
||||
seekArc.setProgress(seekArcProgress);
|
||||
setProgressBarColor(ThemeStore.accentColor(getContext()));
|
||||
|
||||
seekArc.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
|
||||
if (i < 1) {
|
||||
seekArc.setProgress(1);
|
||||
return;
|
||||
}
|
||||
seekArcProgress = i;
|
||||
updateTimeDisplayTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
PreferenceUtil.getInstance().setLastSleepTimerValue(seekArcProgress);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@OnClick({R.id.action_cancel, R.id.action_set})
|
||||
void set(View view) {
|
||||
switch (view.getId()) {
|
||||
case R.id.action_cancel:
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
final PendingIntent previous = makeTimerPendingIntent(PendingIntent.FLAG_NO_CREATE);
|
||||
if (previous != null) {
|
||||
AlarmManager am = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
|
||||
if (am != null) {
|
||||
am.cancel(previous);
|
||||
}
|
||||
previous.cancel();
|
||||
Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.sleep_timer_canceled), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
break;
|
||||
case R.id.action_set:
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
final int minutes = seekArcProgress;
|
||||
PendingIntent pi = makeTimerPendingIntent(PendingIntent.FLAG_CANCEL_CURRENT);
|
||||
final long nextSleepTimerElapsedTime = SystemClock.elapsedRealtime() + minutes * 60 * 1000;
|
||||
PreferenceUtil.getInstance().setNextSleepTimerElapsedRealtime(nextSleepTimerElapsedTime);
|
||||
AlarmManager am = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
|
||||
if (am != null) {
|
||||
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextSleepTimerElapsedTime, pi);
|
||||
}
|
||||
Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.sleep_timer_set, minutes), Toast.LENGTH_SHORT).show();
|
||||
break;
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
|
||||
private void updateTimeDisplayTime() {
|
||||
timerDisplay.setText(String.format(Locale.getDefault(), "%d min", seekArcProgress));
|
||||
}
|
||||
|
||||
private PendingIntent makeTimerPendingIntent(int flag) {
|
||||
return PendingIntent.getService(getActivity(), 0, makeTimerIntent(), flag);
|
||||
}
|
||||
|
||||
private Intent makeTimerIntent() {
|
||||
return new Intent(getActivity(), MusicService.class)
|
||||
.setAction( ACTION_QUIT);
|
||||
}
|
||||
|
||||
private class TimerUpdater extends CountDownTimer {
|
||||
TimerUpdater() {
|
||||
//noinspection ConstantConditions
|
||||
super(PreferenceUtil.getInstance().getNextSleepTimerElapsedRealTime() - SystemClock.elapsedRealtime(), 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTick(long millisUntilFinished) {
|
||||
cancelButton.setText(String.format("%s (%s)", getString(R.string.cancel_current_timer), MusicUtil.getReadableDurationString(millisUntilFinished)));
|
||||
//materialDialog.setActionButton(DialogAction.NEUTRAL, materialDialog.getContext().getString(R.string.cancel_current_timer) + " (" + MusicUtil.getReadableDurationString(millisUntilFinished) + ")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
cancelButton.setText(null);
|
||||
cancelButton.setVisibility(View.GONE);
|
||||
//materialDialog.setActionButton(DialogAction.NEUTRAL, null);
|
||||
}
|
||||
}
|
||||
}
|
138
app/src/main/java/code/name/monkey/retromusic/dialogs/SleepTimerDialog.kt
Executable file
138
app/src/main/java/code/name/monkey/retromusic/dialogs/SleepTimerDialog.kt
Executable file
|
@ -0,0 +1,138 @@
|
|||
package code.name.monkey.retromusic.dialogs
|
||||
|
||||
import android.app.AlarmManager
|
||||
import android.app.PendingIntent
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.graphics.PorterDuff
|
||||
import android.graphics.drawable.ClipDrawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.os.Bundle
|
||||
import android.os.CountDownTimer
|
||||
import android.os.SystemClock
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.SeekBar
|
||||
import android.widget.Toast
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||
import code.name.monkey.retromusic.Constants.ACTION_QUIT
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.service.MusicService
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
|
||||
import kotlinx.android.synthetic.main.dialog_sleep_timer.*
|
||||
import java.util.*
|
||||
|
||||
class SleepTimerDialog : RoundedBottomSheetDialogFragment() {
|
||||
|
||||
private var seekArcProgress: Int = 0
|
||||
private lateinit var timerUpdater: TimerUpdater
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface?) {
|
||||
super.onDismiss(dialog)
|
||||
timerUpdater.cancel()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (makeTimerPendingIntent(PendingIntent.FLAG_NO_CREATE) != null) {
|
||||
timerUpdater.start()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
|
||||
return inflater.inflate(R.layout.dialog_sleep_timer, container, false)
|
||||
}
|
||||
|
||||
private fun setProgressBarColor(dark: Int) {
|
||||
val ld = seekBar.progressDrawable as LayerDrawable
|
||||
val clipDrawable = ld.findDrawableByLayerId(android.R.id.progress) as ClipDrawable
|
||||
clipDrawable.setColorFilter(dark, PorterDuff.Mode.SRC_IN)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
MaterialUtil.setTint(actionSet, true)
|
||||
MaterialUtil.setTint(actionCancel, false)
|
||||
|
||||
title.setTextColor(ThemeStore.textColorPrimary(context!!))
|
||||
timerDisplay!!.setTextColor(ThemeStore.textColorSecondary(context!!))
|
||||
|
||||
timerUpdater = TimerUpdater()
|
||||
|
||||
seekArcProgress = PreferenceUtil.getInstance().lastSleepTimerValue
|
||||
updateTimeDisplayTime()
|
||||
seekBar.progress = seekArcProgress
|
||||
setProgressBarColor(ThemeStore.accentColor(context!!))
|
||||
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) {
|
||||
if (i < 1) {
|
||||
seekBar.progress = 1
|
||||
return
|
||||
}
|
||||
seekArcProgress = i
|
||||
updateTimeDisplayTime()
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar) {
|
||||
|
||||
}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||
PreferenceUtil.getInstance().lastSleepTimerValue = seekArcProgress
|
||||
}
|
||||
})
|
||||
|
||||
actionCancel.setOnClickListener {
|
||||
|
||||
val previous = makeTimerPendingIntent(PendingIntent.FLAG_NO_CREATE)
|
||||
if (previous != null) {
|
||||
val am = activity!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
am.cancel(previous)
|
||||
previous.cancel()
|
||||
Toast.makeText(activity, activity!!.resources.getString(R.string.sleep_timer_canceled), Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
dismiss()
|
||||
}
|
||||
actionSet.setOnClickListener {
|
||||
val minutes = seekArcProgress
|
||||
val pi = makeTimerPendingIntent(PendingIntent.FLAG_CANCEL_CURRENT)
|
||||
val nextSleepTimerElapsedTime = SystemClock.elapsedRealtime() + minutes * 60 * 1000
|
||||
PreferenceUtil.getInstance().setNextSleepTimerElapsedRealtime(nextSleepTimerElapsedTime)
|
||||
val am = activity!!.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextSleepTimerElapsedTime, pi)
|
||||
Toast.makeText(activity, activity!!.resources.getString(R.string.sleep_timer_set, minutes), Toast.LENGTH_SHORT).show()
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTimeDisplayTime() {
|
||||
timerDisplay!!.text = String.format(Locale.getDefault(), "%d min", seekArcProgress)
|
||||
}
|
||||
|
||||
private fun makeTimerPendingIntent(flag: Int): PendingIntent? {
|
||||
return PendingIntent.getService(activity, 0, makeTimerIntent(), flag)
|
||||
}
|
||||
|
||||
private fun makeTimerIntent(): Intent {
|
||||
return Intent(activity, MusicService::class.java)
|
||||
.setAction(ACTION_QUIT)
|
||||
}
|
||||
|
||||
private inner class TimerUpdater internal constructor() : CountDownTimer(PreferenceUtil.getInstance().nextSleepTimerElapsedRealTime - SystemClock.elapsedRealtime(), 1000) {
|
||||
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
actionCancel.text = String.format("%s (%s)", getString(R.string.cancel_current_timer), MusicUtil.getReadableDurationString(millisUntilFinished))
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
actionCancel.text = null
|
||||
actionCancel.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
package code.name.monkey.retromusic.dialogs;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.text.Spanned;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.jaudiotagger.audio.AudioFile;
|
||||
import org.jaudiotagger.audio.AudioFileIO;
|
||||
import org.jaudiotagger.audio.AudioHeader;
|
||||
import org.jaudiotagger.audio.exceptions.CannotReadException;
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
|
||||
import org.jaudiotagger.tag.TagException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import butterknife.BindViews;
|
||||
import butterknife.ButterKnife;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
|
||||
|
||||
/**
|
||||
* @author Karim Abou Zeid (kabouzeid), Aidan Follestad (afollestad)
|
||||
*/
|
||||
public class SongDetailDialog extends RoundedBottomSheetDialogFragment {
|
||||
|
||||
public static final String TAG = SongDetailDialog.class.getSimpleName();
|
||||
@BindViews({R.id.title,
|
||||
R.id.file_name,
|
||||
R.id.file_path,
|
||||
R.id.file_size,
|
||||
R.id.file_format,
|
||||
R.id.track_length,
|
||||
R.id.bitrate,
|
||||
R.id.sampling_rate})
|
||||
List<TextView> textViews;
|
||||
|
||||
@NonNull
|
||||
public static SongDetailDialog create(Song song) {
|
||||
SongDetailDialog dialog = new SongDetailDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable("song", song);
|
||||
dialog.setArguments(args);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
private static Spanned makeTextWithTitle(@NonNull Context context, int titleResId, String text) {
|
||||
return Html.fromHtml("<b>" + context.getResources().getString(titleResId) + ": " + "</b>" + text);
|
||||
}
|
||||
|
||||
private static String getFileSizeString(long sizeInBytes) {
|
||||
long fileSizeInKB = sizeInBytes / 1024;
|
||||
long fileSizeInMB = fileSizeInKB / 1024;
|
||||
return fileSizeInMB + " MB";
|
||||
}
|
||||
|
||||
private void setTextColor(List<TextView> textColor) {
|
||||
for (TextView textView : textColor) {
|
||||
//noinspection ConstantConditions
|
||||
textView.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View dialogView = inflater.inflate(R.layout.dialog_file_details, container, false);
|
||||
ButterKnife.bind(this, dialogView);
|
||||
Context context = getContext();
|
||||
|
||||
setTextColor(textViews);
|
||||
|
||||
textViews.get(1).setText(makeTextWithTitle(context, R.string.label_file_name, "-"));
|
||||
textViews.get(2).setText(makeTextWithTitle(context, R.string.label_file_path, "-"));
|
||||
textViews.get(3).setText(makeTextWithTitle(context, R.string.label_file_size, "-"));
|
||||
textViews.get(4).setText(makeTextWithTitle(context, R.string.label_file_format, "-"));
|
||||
textViews.get(5).setText(makeTextWithTitle(context, R.string.label_track_length, "-"));
|
||||
textViews.get(6).setText(makeTextWithTitle(context, R.string.label_bit_rate, "-"));
|
||||
textViews.get(7).setText(makeTextWithTitle(context, R.string.label_sampling_rate, "-"));
|
||||
|
||||
final Song song = getArguments().getParcelable("song");
|
||||
if (song != null) {
|
||||
final File songFile = new File(song.getData());
|
||||
if (songFile.exists()) {
|
||||
textViews.get(1).setText(makeTextWithTitle(context, R.string.label_file_name, songFile.getName()));
|
||||
textViews.get(2).setText(makeTextWithTitle(context, R.string.label_file_path, songFile.getAbsolutePath()));
|
||||
textViews.get(3).setText(makeTextWithTitle(context, R.string.label_file_size, getFileSizeString(songFile.length())));
|
||||
try {
|
||||
AudioFile audioFile = AudioFileIO.read(songFile);
|
||||
AudioHeader audioHeader = audioFile.getAudioHeader();
|
||||
|
||||
textViews.get(4).setText(makeTextWithTitle(context, R.string.label_file_format, audioHeader.getFormat()));
|
||||
textViews.get(5).setText(makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(audioHeader.getTrackLength() * 1000)));
|
||||
textViews.get(6).setText(makeTextWithTitle(context, R.string.label_bit_rate, audioHeader.getBitRate() + " kb/s"));
|
||||
textViews.get(7).setText(makeTextWithTitle(context, R.string.label_sampling_rate, audioHeader.getSampleRate() + " Hz"));
|
||||
} catch (@NonNull CannotReadException | IOException | TagException | ReadOnlyFileException | InvalidAudioFrameException e) {
|
||||
Log.e(TAG, "error while reading the song file", e);
|
||||
// fallback
|
||||
textViews.get(5).setText(makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(song.getDuration())));
|
||||
}
|
||||
} else {
|
||||
// fallback
|
||||
textViews.get(1).setText(makeTextWithTitle(context, R.string.label_file_name, song.getTitle()));
|
||||
textViews.get(5).setText(makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(song.getDuration())));
|
||||
}
|
||||
}
|
||||
|
||||
return dialogView;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
package code.name.monkey.retromusic.dialogs
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.text.Html
|
||||
import android.text.Spanned
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
|
||||
import kotlinx.android.synthetic.main.dialog_file_details.*
|
||||
import org.jaudiotagger.audio.AudioFileIO
|
||||
import org.jaudiotagger.audio.exceptions.CannotReadException
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException
|
||||
import org.jaudiotagger.tag.TagException
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
class SongDetailDialog : RoundedBottomSheetDialogFragment() {
|
||||
|
||||
private fun setTextColor(textColor: List<TextView>) {
|
||||
for (textView in textColor) {
|
||||
|
||||
textView.setTextColor(ThemeStore.textColorPrimary(context!!))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
val dialogView = inflater.inflate(R.layout.dialog_file_details, container, false)
|
||||
val context = context
|
||||
|
||||
fileName.text = makeTextWithTitle(context!!, R.string.label_file_name, "-")
|
||||
filePath.text = makeTextWithTitle(context, R.string.label_file_path, "-")
|
||||
fileSize.text = makeTextWithTitle(context, R.string.label_file_size, "-")
|
||||
fileFormat.text = makeTextWithTitle(context, R.string.label_file_format, "-")
|
||||
trackLength.text = makeTextWithTitle(context, R.string.label_track_length, "-")
|
||||
bitrate.text = makeTextWithTitle(context, R.string.label_bit_rate, "-")
|
||||
samplingRate.text = makeTextWithTitle(context, R.string.label_sampling_rate, "-")
|
||||
|
||||
val song = arguments!!.getParcelable<Song>("song")
|
||||
if (song != null) {
|
||||
val songFile = File(song.data)
|
||||
if (songFile.exists()) {
|
||||
fileName.text = makeTextWithTitle(context, R.string.label_file_name, songFile.name)
|
||||
filePath.text = makeTextWithTitle(context, R.string.label_file_path, songFile.absolutePath)
|
||||
fileSize.text = makeTextWithTitle(context, R.string.label_file_size, getFileSizeString(songFile.length()))
|
||||
try {
|
||||
val audioFile = AudioFileIO.read(songFile)
|
||||
val audioHeader = audioFile.audioHeader
|
||||
|
||||
fileFormat.text = makeTextWithTitle(context, R.string.label_file_format, audioHeader.format)
|
||||
trackLength.text = makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString((audioHeader.trackLength * 1000).toLong()))
|
||||
bitrate.text = makeTextWithTitle(context, R.string.label_bit_rate, audioHeader.bitRate + " kb/s")
|
||||
samplingRate.text = makeTextWithTitle(context, R.string.label_sampling_rate, audioHeader.sampleRate + " Hz")
|
||||
} catch (e: CannotReadException) {
|
||||
Log.e(TAG, "error while reading the song file", e)
|
||||
// fallback
|
||||
trackLength.text = makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(song.duration))
|
||||
} catch (e: IOException) {
|
||||
Log.e(TAG, "error while reading the song file", e)
|
||||
trackLength.text = makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(song.duration))
|
||||
} catch (e: TagException) {
|
||||
Log.e(TAG, "error while reading the song file", e)
|
||||
trackLength.text = makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(song.duration))
|
||||
} catch (e: ReadOnlyFileException) {
|
||||
Log.e(TAG, "error while reading the song file", e)
|
||||
trackLength.text = makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(song.duration))
|
||||
} catch (e: InvalidAudioFrameException) {
|
||||
Log.e(TAG, "error while reading the song file", e)
|
||||
trackLength.text = makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(song.duration))
|
||||
}
|
||||
|
||||
} else {
|
||||
// fallback
|
||||
fileName.text = makeTextWithTitle(context, R.string.label_file_name, song.title)
|
||||
trackLength.text = makeTextWithTitle(context, R.string.label_track_length, MusicUtil.getReadableDurationString(song.duration))
|
||||
}
|
||||
}
|
||||
|
||||
return dialogView
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
val TAG = SongDetailDialog::class.java.simpleName
|
||||
|
||||
|
||||
fun create(song: Song): SongDetailDialog {
|
||||
val dialog = SongDetailDialog()
|
||||
val args = Bundle()
|
||||
args.putParcelable("song", song)
|
||||
dialog.arguments = args
|
||||
return dialog
|
||||
}
|
||||
|
||||
private fun makeTextWithTitle(context: Context, titleResId: Int, text: String?): Spanned {
|
||||
return Html.fromHtml("<b>" + context.resources.getString(titleResId) + ": " + "</b>" + text)
|
||||
}
|
||||
|
||||
private fun getFileSizeString(sizeInBytes: Long): String {
|
||||
val fileSizeInKB = sizeInBytes / 1024
|
||||
val fileSizeInMB = fileSizeInKB / 1024
|
||||
return fileSizeInMB.toString() + " MB"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package code.name.monkey.retromusic.dialogs;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import code.name.monkey.appthemehelper.ThemeStore;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
|
||||
|
||||
|
||||
public class SongShareDialog extends RoundedBottomSheetDialogFragment {
|
||||
@BindView(R.id.option_1)
|
||||
TextView audioFile;
|
||||
@BindView(R.id.option_2)
|
||||
TextView audioText;
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
|
||||
@NonNull
|
||||
public static SongShareDialog create(final Song song) {
|
||||
final SongShareDialog dialog = new SongShareDialog();
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable("song", song);
|
||||
dialog.setArguments(args);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View layout = inflater.inflate(R.layout.dialog_file_share, container, false);
|
||||
ButterKnife.bind(this, layout);
|
||||
return layout;
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
final Song song = getArguments().getParcelable("song");
|
||||
|
||||
audioFile.setText(getString(R.string.currently_listening_to_x_by_x, song.getTitle(), song.getArtistName()));
|
||||
audioFile.setTextColor(ThemeStore.textColorSecondary(getContext()));
|
||||
audioText.setTextColor(ThemeStore.textColorSecondary(getContext()));
|
||||
title.setTextColor(ThemeStore.textColorPrimary(getContext()));
|
||||
}
|
||||
|
||||
@OnClick({R.id.option_2, R.id.option_1})
|
||||
void onClick(View view) {
|
||||
final Song song = getArguments().getParcelable("song");
|
||||
final String currentlyListening = getString(R.string.currently_listening_to_x_by_x, song.getTitle(), song.getArtistName());
|
||||
switch (view.getId()) {
|
||||
case R.id.option_1:
|
||||
startActivity(Intent.createChooser(
|
||||
MusicUtil.createShareSongFileIntent(song, getContext()), null));
|
||||
break;
|
||||
case R.id.option_2:
|
||||
getActivity().startActivity(Intent.createChooser(new Intent().setAction(Intent.ACTION_SEND)
|
||||
.putExtra(Intent.EXTRA_TEXT, currentlyListening)
|
||||
.setType("text/plain"), null));
|
||||
break;
|
||||
}
|
||||
dismiss();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package code.name.monkey.retromusic.dialogs
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
|
||||
import kotlinx.android.synthetic.main.dialog_file_share.*
|
||||
|
||||
|
||||
class SongShareDialog : RoundedBottomSheetDialogFragment() {
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
return inflater.inflate(R.layout.dialog_file_share, container, false)
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val song = arguments!!.getParcelable<Song>("song")!!
|
||||
|
||||
audioFile.text = getString(R.string.currently_listening_to_x_by_x, song.title, song.artistName)
|
||||
audioFile.setTextColor(ThemeStore.textColorSecondary(context!!))
|
||||
audioText.setTextColor(ThemeStore.textColorSecondary(context!!))
|
||||
title.setTextColor(ThemeStore.textColorPrimary(context!!))
|
||||
|
||||
audioFile.setOnClickListener {
|
||||
MusicUtil.createShareSongFileIntent(song, context)
|
||||
dismiss()
|
||||
}
|
||||
audioText.setOnClickListener {
|
||||
val currentlyListening = getString(R.string.currently_listening_to_x_by_x, song.title, song.artistName)
|
||||
activity!!.startActivity(Intent.createChooser(Intent().setAction(Intent.ACTION_SEND)
|
||||
.putExtra(Intent.EXTRA_TEXT, currentlyListening)
|
||||
.setType("text/plain"), null))
|
||||
dismiss()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun create(song: Song): SongShareDialog {
|
||||
val dialog = SongShareDialog()
|
||||
val args = Bundle()
|
||||
args.putParcelable("song", song)
|
||||
dialog.arguments = args
|
||||
return dialog
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,141 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.BitmapRequestBuilder;
|
||||
import com.bumptech.glide.DrawableRequestBuilder;
|
||||
import com.bumptech.glide.DrawableTypeRequest;
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.RequestManager;
|
||||
import com.bumptech.glide.load.Key;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.App;
|
||||
import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.util.ArtistSignatureUtil;
|
||||
import code.name.monkey.retromusic.util.CustomArtistImageUtil;
|
||||
|
||||
public class ArtistGlideRequest {
|
||||
|
||||
private static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
|
||||
private static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.ALL;
|
||||
private static final int DEFAULT_ERROR_IMAGE = R.drawable.default_artist_art;
|
||||
|
||||
private static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Artist artist,
|
||||
boolean noCustomImage, boolean forceDownload) {
|
||||
boolean hasCustomImage = CustomArtistImageUtil.getInstance(App.Companion.getInstance())
|
||||
.hasCustomArtistImage(artist);
|
||||
if (noCustomImage || !hasCustomImage) {
|
||||
return requestManager.load(new ArtistImage(artist.getName(), forceDownload));
|
||||
} else {
|
||||
return requestManager.load(CustomArtistImageUtil.getFile(artist));
|
||||
}
|
||||
}
|
||||
|
||||
private static Key createSignature(Artist artist) {
|
||||
return ArtistSignatureUtil.getInstance(App.Companion.getInstance())
|
||||
.getArtistSignature(artist.getName());
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
final RequestManager requestManager;
|
||||
final Artist artist;
|
||||
boolean noCustomImage;
|
||||
boolean forceDownload;
|
||||
|
||||
private Builder(@NonNull RequestManager requestManager, Artist artist) {
|
||||
this.requestManager = requestManager;
|
||||
this.artist = artist;
|
||||
}
|
||||
|
||||
public static Builder from(@NonNull RequestManager requestManager, Artist artist) {
|
||||
return new Builder(requestManager, artist);
|
||||
}
|
||||
|
||||
public PaletteBuilder generatePalette(Context context) {
|
||||
return new PaletteBuilder(this, context);
|
||||
}
|
||||
|
||||
public BitmapBuilder asBitmap() {
|
||||
return new BitmapBuilder(this);
|
||||
}
|
||||
|
||||
public Builder noCustomImage(boolean noCustomImage) {
|
||||
this.noCustomImage = noCustomImage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder forceDownload(boolean forceDownload) {
|
||||
this.forceDownload = forceDownload;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DrawableRequestBuilder<GlideDrawable> build() {
|
||||
//noinspection unchecked
|
||||
return createBaseRequest(requestManager, artist, noCustomImage, forceDownload)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.priority(Priority.LOW)
|
||||
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||
.signature(createSignature(artist));
|
||||
}
|
||||
}
|
||||
|
||||
public static class BitmapBuilder {
|
||||
|
||||
private final Builder builder;
|
||||
|
||||
BitmapBuilder(Builder builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
public BitmapRequestBuilder<?, Bitmap> build() {
|
||||
//noinspection unchecked
|
||||
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage,
|
||||
builder.forceDownload)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.priority(Priority.LOW)
|
||||
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||
.signature(createSignature(builder.artist));
|
||||
}
|
||||
}
|
||||
|
||||
public static class PaletteBuilder {
|
||||
|
||||
final Context context;
|
||||
private final Builder builder;
|
||||
|
||||
PaletteBuilder(Builder builder, Context context) {
|
||||
this.builder = builder;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public BitmapRequestBuilder<?, BitmapPaletteWrapper> build() {
|
||||
//noinspection unchecked
|
||||
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage,
|
||||
builder.forceDownload)
|
||||
.asBitmap()
|
||||
.transcode(new BitmapPaletteTranscoder(context), BitmapPaletteWrapper.class)
|
||||
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.priority(Priority.LOW)
|
||||
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||
.signature(createSignature(builder.artist));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package code.name.monkey.retromusic.glide
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.glide.artistimage.ArtistImage
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.util.ArtistSignatureUtil
|
||||
import code.name.monkey.retromusic.util.CustomArtistImageUtil
|
||||
import com.bumptech.glide.*
|
||||
import com.bumptech.glide.load.Key
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.request.target.Target
|
||||
|
||||
object ArtistGlideRequest {
|
||||
|
||||
private const val DEFAULT_ANIMATION = android.R.anim.fade_in
|
||||
private val DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.ALL
|
||||
private const val DEFAULT_ERROR_IMAGE = R.drawable.default_artist_art
|
||||
|
||||
private fun createBaseRequest(requestManager: RequestManager, artist: Artist, noCustomImage: Boolean, forceDownload: Boolean): DrawableTypeRequest<*> {
|
||||
val hasCustomImage = CustomArtistImageUtil.getInstance(App.instance)
|
||||
.hasCustomArtistImage(artist)
|
||||
return if (noCustomImage || !hasCustomImage) {
|
||||
requestManager.load(ArtistImage(artist.name, forceDownload))
|
||||
} else {
|
||||
requestManager.load(CustomArtistImageUtil.getFile(artist))
|
||||
}
|
||||
}
|
||||
|
||||
private fun createSignature(artist: Artist): Key {
|
||||
return ArtistSignatureUtil.getInstance(App.instance)
|
||||
.getArtistSignature(artist.name)
|
||||
}
|
||||
|
||||
class Builder private constructor(internal val requestManager: RequestManager, internal val artist: Artist) {
|
||||
internal var noCustomImage: Boolean = false
|
||||
internal var forceDownload: Boolean = false
|
||||
|
||||
fun generatePalette(context: Context): PaletteBuilder {
|
||||
return PaletteBuilder(this, context)
|
||||
}
|
||||
|
||||
fun asBitmap(): BitmapBuilder {
|
||||
return BitmapBuilder(this)
|
||||
}
|
||||
|
||||
fun noCustomImage(noCustomImage: Boolean): Builder {
|
||||
this.noCustomImage = noCustomImage
|
||||
return this
|
||||
}
|
||||
|
||||
fun forceDownload(forceDownload: Boolean): Builder {
|
||||
this.forceDownload = forceDownload
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): DrawableRequestBuilder<out Any> {
|
||||
return createBaseRequest(requestManager, artist, noCustomImage, forceDownload)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.priority(Priority.LOW)
|
||||
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||
.signature(createSignature(artist))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun from(requestManager: RequestManager, artist: Artist): Builder {
|
||||
return Builder(requestManager, artist)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BitmapBuilder internal constructor(private val builder: Builder) {
|
||||
|
||||
fun build(): BitmapRequestBuilder<*, Bitmap> {
|
||||
|
||||
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage,
|
||||
builder.forceDownload)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.priority(Priority.LOW)
|
||||
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||
.signature(createSignature(builder.artist))
|
||||
}
|
||||
}
|
||||
|
||||
class PaletteBuilder internal constructor(private val builder: Builder, internal val context: Context) {
|
||||
|
||||
fun build(): BitmapRequestBuilder<*, BitmapPaletteWrapper> {
|
||||
|
||||
return createBaseRequest(builder.requestManager, builder.artist, builder.noCustomImage,
|
||||
builder.forceDownload)
|
||||
.asBitmap()
|
||||
.transcode(BitmapPaletteTranscoder(context), BitmapPaletteWrapper::class.java)
|
||||
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.priority(Priority.LOW)
|
||||
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
|
||||
.signature(createSignature(builder.artist))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Build;
|
||||
import android.renderscript.Allocation;
|
||||
import android.renderscript.Element;
|
||||
import android.renderscript.RSRuntimeException;
|
||||
import android.renderscript.RenderScript;
|
||||
import android.renderscript.ScriptIntrinsicBlur;
|
||||
import androidx.annotation.FloatRange;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
|
||||
import code.name.monkey.retromusic.helper.StackBlur;
|
||||
|
||||
import code.name.monkey.retromusic.BuildConfig;
|
||||
import code.name.monkey.retromusic.util.ImageUtil;
|
||||
|
||||
|
||||
public class BlurTransformation extends BitmapTransformation {
|
||||
static final float DEFAULT_BLUR_RADIUS = 5f;
|
||||
|
||||
private Context context;
|
||||
private float blurRadius;
|
||||
private int sampling;
|
||||
|
||||
private BlurTransformation(Builder builder) {
|
||||
super(builder.context);
|
||||
init(builder);
|
||||
}
|
||||
|
||||
private BlurTransformation(Builder builder, BitmapPool bitmapPool) {
|
||||
super(bitmapPool);
|
||||
init(builder);
|
||||
}
|
||||
|
||||
private void init(Builder builder) {
|
||||
this.context = builder.context;
|
||||
this.blurRadius = builder.blurRadius;
|
||||
this.sampling = builder.sampling;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
|
||||
int sampling;
|
||||
if (this.sampling == 0) {
|
||||
sampling = ImageUtil.calculateInSampleSize(toTransform.getWidth(), toTransform.getHeight(), 100);
|
||||
} else {
|
||||
sampling = this.sampling;
|
||||
}
|
||||
|
||||
int width = toTransform.getWidth();
|
||||
int height = toTransform.getHeight();
|
||||
int scaledWidth = width / sampling;
|
||||
int scaledHeight = height / sampling;
|
||||
|
||||
Bitmap out = pool.get(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
|
||||
if (out == null) {
|
||||
out = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888);
|
||||
}
|
||||
|
||||
Canvas canvas = new Canvas(out);
|
||||
canvas.scale(1 / (float) sampling, 1 / (float) sampling);
|
||||
Paint paint = new Paint();
|
||||
paint.setFlags(Paint.FILTER_BITMAP_FLAG);
|
||||
canvas.drawBitmap(toTransform, 0, 0, paint);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
try {
|
||||
final RenderScript rs = RenderScript.create(context.getApplicationContext());
|
||||
final Allocation input = Allocation.createFromBitmap(rs, out, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
|
||||
final Allocation output = Allocation.createTyped(rs, input.getType());
|
||||
final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
|
||||
|
||||
script.setRadius(blurRadius);
|
||||
script.setInput(input);
|
||||
script.forEach(output);
|
||||
|
||||
output.copyTo(out);
|
||||
|
||||
rs.destroy();
|
||||
|
||||
return out;
|
||||
|
||||
} catch (RSRuntimeException e) {
|
||||
// on some devices RenderScript.create() throws: android.support.v8.renderscript.RSRuntimeException: Error loading libRSSupport library
|
||||
if (BuildConfig.DEBUG) e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return StackBlur.blur(out, blurRadius);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "BlurTransformation(radius=" + blurRadius + ", sampling=" + sampling + ")";
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private Context context;
|
||||
private BitmapPool bitmapPool;
|
||||
private float blurRadius = DEFAULT_BLUR_RADIUS;
|
||||
private int sampling;
|
||||
|
||||
public Builder(@NonNull Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param blurRadius The radius to use. Must be between 0 and 25. Default is 5.
|
||||
* @return the same Builder
|
||||
*/
|
||||
public Builder blurRadius(@FloatRange(from = 0.0f, to = 25.0f) float blurRadius) {
|
||||
this.blurRadius = blurRadius;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sampling The inSampleSize to use. Must be a power of 2, or 1 for no down sampling or 0 for auto detect sampling. Default is 0.
|
||||
* @return the same Builder
|
||||
*/
|
||||
public Builder sampling(int sampling) {
|
||||
this.sampling = sampling;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bitmapPool The BitmapPool to use.
|
||||
* @return the same Builder
|
||||
*/
|
||||
public Builder bitmapPool(BitmapPool bitmapPool) {
|
||||
this.bitmapPool = bitmapPool;
|
||||
return this;
|
||||
}
|
||||
|
||||
public BlurTransformation build() {
|
||||
if (bitmapPool != null) {
|
||||
return new BlurTransformation(this, bitmapPool);
|
||||
}
|
||||
return new BlurTransformation(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package code.name.monkey.retromusic.glide
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.os.Build
|
||||
import android.renderscript.Allocation
|
||||
import android.renderscript.Element
|
||||
import android.renderscript.RSRuntimeException
|
||||
import android.renderscript.RenderScript
|
||||
import android.renderscript.ScriptIntrinsicBlur
|
||||
import androidx.annotation.FloatRange
|
||||
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||
import code.name.monkey.retromusic.helper.StackBlur
|
||||
|
||||
import code.name.monkey.retromusic.BuildConfig
|
||||
import code.name.monkey.retromusic.util.ImageUtil
|
||||
|
||||
|
||||
class BlurTransformation : BitmapTransformation {
|
||||
|
||||
private var context: Context? = null
|
||||
private var blurRadius: Float = 0.toFloat()
|
||||
private var sampling: Int = 0
|
||||
|
||||
private constructor(builder: Builder) : super(builder.context) {
|
||||
init(builder)
|
||||
}
|
||||
|
||||
private constructor(builder: Builder, bitmapPool: BitmapPool) : super(bitmapPool) {
|
||||
init(builder)
|
||||
}
|
||||
|
||||
private fun init(builder: Builder) {
|
||||
this.context = builder.context
|
||||
this.blurRadius = builder.blurRadius
|
||||
this.sampling = builder.sampling
|
||||
}
|
||||
|
||||
|
||||
override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap? {
|
||||
val sampling: Int
|
||||
if (this.sampling == 0) {
|
||||
sampling = ImageUtil.calculateInSampleSize(toTransform.width, toTransform.height, 100)
|
||||
} else {
|
||||
sampling = this.sampling
|
||||
}
|
||||
|
||||
val width = toTransform.width
|
||||
val height = toTransform.height
|
||||
val scaledWidth = width / sampling
|
||||
val scaledHeight = height / sampling
|
||||
|
||||
var out: Bitmap? = pool.get(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888)
|
||||
if (out == null) {
|
||||
out = Bitmap.createBitmap(scaledWidth, scaledHeight, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
|
||||
val canvas = Canvas(out!!)
|
||||
canvas.scale(1 / sampling.toFloat(), 1 / sampling.toFloat())
|
||||
val paint = Paint()
|
||||
paint.flags = Paint.FILTER_BITMAP_FLAG
|
||||
canvas.drawBitmap(toTransform, 0f, 0f, paint)
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 17) {
|
||||
try {
|
||||
val rs = RenderScript.create(context!!.applicationContext)
|
||||
val input = Allocation.createFromBitmap(rs, out, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT)
|
||||
val output = Allocation.createTyped(rs, input.type)
|
||||
val script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))
|
||||
|
||||
script.setRadius(blurRadius)
|
||||
script.setInput(input)
|
||||
script.forEach(output)
|
||||
|
||||
output.copyTo(out)
|
||||
|
||||
rs.destroy()
|
||||
|
||||
return out
|
||||
|
||||
} catch (e: RSRuntimeException) {
|
||||
// on some devices RenderScript.create() throws: android.support.v8.renderscript.RSRuntimeException: Error loading libRSSupport library
|
||||
if (BuildConfig.DEBUG) e.printStackTrace()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return StackBlur.blur(out, blurRadius)
|
||||
}
|
||||
|
||||
override fun getId(): String {
|
||||
return "BlurTransformation(radius=$blurRadius, sampling=$sampling)"
|
||||
}
|
||||
|
||||
class Builder(internal val context: Context) {
|
||||
private var bitmapPool: BitmapPool? = null
|
||||
internal var blurRadius = DEFAULT_BLUR_RADIUS
|
||||
internal var sampling: Int = 0
|
||||
|
||||
/**
|
||||
* @param blurRadius The radius to use. Must be between 0 and 25. Default is 5.
|
||||
* @return the same Builder
|
||||
*/
|
||||
fun blurRadius(@FloatRange(from = 0.0, to = 25.0) blurRadius: Float): Builder {
|
||||
this.blurRadius = blurRadius
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sampling The inSampleSize to use. Must be a power of 2, or 1 for no down sampling or 0 for auto detect sampling. Default is 0.
|
||||
* @return the same Builder
|
||||
*/
|
||||
fun sampling(sampling: Int): Builder {
|
||||
this.sampling = sampling
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bitmapPool The BitmapPool to use.
|
||||
* @return the same Builder
|
||||
*/
|
||||
fun bitmapPool(bitmapPool: BitmapPool): Builder {
|
||||
this.bitmapPool = bitmapPool
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): BlurTransformation {
|
||||
return if (bitmapPool != null) {
|
||||
BlurTransformation(this, bitmapPool!!)
|
||||
} else BlurTransformation(this)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal const val DEFAULT_BLUR_RADIUS = 5f
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.GlideBuilder;
|
||||
import com.bumptech.glide.module.GlideModule;
|
||||
import code.name.monkey.retromusic.glide.artistimage.ArtistImage;
|
||||
import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader;
|
||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover;
|
||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverLoader;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
public class RetroMusicGlideModule implements GlideModule {
|
||||
@Override
|
||||
public void applyOptions(Context context, GlideBuilder builder) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerComponents(Context context, Glide glide) {
|
||||
glide.register(AudioFileCover.class, InputStream.class, new AudioFileCoverLoader.Factory());
|
||||
glide.register(ArtistImage.class, InputStream.class, new ArtistImageLoader.Factory(context));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package code.name.monkey.retromusic.glide
|
||||
|
||||
import android.content.Context
|
||||
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.GlideBuilder
|
||||
import com.bumptech.glide.module.GlideModule
|
||||
import code.name.monkey.retromusic.glide.artistimage.ArtistImage
|
||||
import code.name.monkey.retromusic.glide.artistimage.ArtistImageLoader
|
||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
|
||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCoverLoader
|
||||
|
||||
import java.io.InputStream
|
||||
|
||||
|
||||
class RetroMusicGlideModule : GlideModule {
|
||||
override fun applyOptions(context: Context, builder: GlideBuilder) {
|
||||
|
||||
}
|
||||
|
||||
override fun registerComponents(context: Context, glide: Glide) {
|
||||
glide.register(AudioFileCover::class.java, InputStream::class.java, AudioFileCoverLoader.Factory())
|
||||
glide.register(ArtistImage::class.java, InputStream::class.java, ArtistImageLoader.Factory(context))
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import androidx.annotation.NonNull;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover;
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import com.bumptech.glide.BitmapRequestBuilder;
|
||||
import com.bumptech.glide.DrawableRequestBuilder;
|
||||
import com.bumptech.glide.DrawableTypeRequest;
|
||||
import com.bumptech.glide.RequestManager;
|
||||
import com.bumptech.glide.load.Key;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
|
||||
import com.bumptech.glide.signature.MediaStoreSignature;
|
||||
|
||||
|
||||
public class SongGlideRequest {
|
||||
|
||||
static final DiskCacheStrategy DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.NONE;
|
||||
static final int DEFAULT_ANIMATION = android.R.anim.fade_in;
|
||||
static final int DEFAULT_ERROR_IMAGE = R.drawable.default_album_art;
|
||||
|
||||
static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Song song,
|
||||
boolean ignoreMediaStore) {
|
||||
if (ignoreMediaStore) {
|
||||
return requestManager.load(new AudioFileCover(song.getData()));
|
||||
} else {
|
||||
return requestManager.loadFromMediaStore(MusicUtil.getMediaStoreAlbumCoverUri(song.getAlbumId()));
|
||||
}
|
||||
}
|
||||
|
||||
static Key createSignature(Song song) {
|
||||
return new MediaStoreSignature("", song.getDateModified(), 0);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
final RequestManager requestManager;
|
||||
final Song song;
|
||||
boolean ignoreMediaStore;
|
||||
|
||||
private Builder(@NonNull RequestManager requestManager, Song song) {
|
||||
this.requestManager = requestManager;
|
||||
this.song = song;
|
||||
}
|
||||
|
||||
public static Builder from(@NonNull RequestManager requestManager, Song song) {
|
||||
return new Builder(requestManager, song);
|
||||
}
|
||||
|
||||
public PaletteBuilder generatePalette(Context context) {
|
||||
return new PaletteBuilder(this, context);
|
||||
}
|
||||
|
||||
public BitmapBuilder asBitmap() {
|
||||
return new BitmapBuilder(this);
|
||||
}
|
||||
|
||||
public Builder checkIgnoreMediaStore(Context context) {
|
||||
return ignoreMediaStore(PreferenceUtil.getInstance().ignoreMediaStoreArtwork());
|
||||
}
|
||||
|
||||
Builder ignoreMediaStore(boolean ignoreMediaStore) {
|
||||
this.ignoreMediaStore = ignoreMediaStore;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DrawableRequestBuilder<GlideDrawable> build() {
|
||||
//noinspection unchecked
|
||||
return createBaseRequest(requestManager, song, ignoreMediaStore)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(song));
|
||||
}
|
||||
}
|
||||
|
||||
public static class BitmapBuilder {
|
||||
|
||||
private final Builder builder;
|
||||
|
||||
BitmapBuilder(Builder builder) {
|
||||
this.builder = builder;
|
||||
}
|
||||
|
||||
public BitmapRequestBuilder<?, Bitmap> build() {
|
||||
//noinspection unchecked
|
||||
return createBaseRequest(builder.requestManager, builder.song, builder.ignoreMediaStore)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(builder.song));
|
||||
}
|
||||
}
|
||||
|
||||
public static class PaletteBuilder {
|
||||
|
||||
final Context context;
|
||||
private final Builder builder;
|
||||
|
||||
PaletteBuilder(Builder builder, Context context) {
|
||||
this.builder = builder;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public BitmapRequestBuilder<?, BitmapPaletteWrapper> build() {
|
||||
//noinspection unchecked
|
||||
return createBaseRequest(builder.requestManager, builder.song, builder.ignoreMediaStore)
|
||||
.asBitmap()
|
||||
.transcode(new BitmapPaletteTranscoder(context), BitmapPaletteWrapper.class)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(builder.song));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package code.name.monkey.retromusic.glide
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.bumptech.glide.BitmapRequestBuilder
|
||||
import com.bumptech.glide.DrawableRequestBuilder
|
||||
import com.bumptech.glide.DrawableTypeRequest
|
||||
import com.bumptech.glide.RequestManager
|
||||
import com.bumptech.glide.load.Key
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.signature.MediaStoreSignature
|
||||
|
||||
|
||||
object SongGlideRequest {
|
||||
|
||||
internal val DEFAULT_DISK_CACHE_STRATEGY = DiskCacheStrategy.NONE
|
||||
internal const val DEFAULT_ANIMATION = android.R.anim.fade_in
|
||||
internal const val DEFAULT_ERROR_IMAGE = R.drawable.default_album_art
|
||||
|
||||
internal fun createBaseRequest(requestManager: RequestManager, song: Song,
|
||||
ignoreMediaStore: Boolean): DrawableTypeRequest<*> {
|
||||
return if (ignoreMediaStore) {
|
||||
requestManager.load(AudioFileCover(song.data!!))
|
||||
} else {
|
||||
requestManager.loadFromMediaStore(MusicUtil.getMediaStoreAlbumCoverUri(song.albumId))
|
||||
}
|
||||
}
|
||||
|
||||
internal fun createSignature(song: Song): Key {
|
||||
return MediaStoreSignature("", song.dateModified, 0)
|
||||
}
|
||||
|
||||
class Builder private constructor(internal val requestManager: RequestManager, internal val song: Song) {
|
||||
internal var ignoreMediaStore: Boolean = false
|
||||
|
||||
fun generatePalette(context: Context): PaletteBuilder {
|
||||
return PaletteBuilder(this, context)
|
||||
}
|
||||
|
||||
fun asBitmap(): BitmapBuilder {
|
||||
return BitmapBuilder(this)
|
||||
}
|
||||
|
||||
fun checkIgnoreMediaStore(context: Context): Builder {
|
||||
return ignoreMediaStore(PreferenceUtil.getInstance().ignoreMediaStoreArtwork())
|
||||
}
|
||||
|
||||
fun ignoreMediaStore(ignoreMediaStore: Boolean): Builder {
|
||||
this.ignoreMediaStore = ignoreMediaStore
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(): DrawableRequestBuilder<out Any> {
|
||||
return createBaseRequest(requestManager, song, ignoreMediaStore)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(song))
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun from(requestManager: RequestManager, song: Song): Builder {
|
||||
return Builder(requestManager, song)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BitmapBuilder internal constructor(private val builder: Builder) {
|
||||
|
||||
fun build(): BitmapRequestBuilder<*, Bitmap> {
|
||||
|
||||
return createBaseRequest(builder.requestManager, builder.song, builder.ignoreMediaStore)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(builder.song))
|
||||
}
|
||||
}
|
||||
|
||||
class PaletteBuilder internal constructor(private val builder: Builder, internal val context: Context) {
|
||||
|
||||
fun build(): BitmapRequestBuilder<*, BitmapPaletteWrapper> {
|
||||
|
||||
return createBaseRequest(builder.requestManager, builder.song, builder.ignoreMediaStore)
|
||||
.asBitmap()
|
||||
.transcode(BitmapPaletteTranscoder(context), BitmapPaletteWrapper::class.java)
|
||||
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
|
||||
.error(DEFAULT_ERROR_IMAGE)
|
||||
.animate(DEFAULT_ANIMATION)
|
||||
.signature(createSignature(builder.song))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.artistimage;
|
||||
|
||||
|
||||
public class ArtistImage {
|
||||
public final String artistName;
|
||||
public final boolean skipOkHttpCache;
|
||||
|
||||
public ArtistImage(String artistName, boolean skipOkHttpCache) {
|
||||
this.artistName = artistName;
|
||||
this.skipOkHttpCache = skipOkHttpCache;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package code.name.monkey.retromusic.glide.artistimage
|
||||
|
||||
|
||||
class ArtistImage(val artistName: String, val skipOkHttpCache: Boolean)
|
|
@ -1,83 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.artistimage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
import com.bumptech.glide.load.model.GlideUrl;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import code.name.monkey.retromusic.rest.LastFMRestClient;
|
||||
import code.name.monkey.retromusic.rest.model.LastFmArtist;
|
||||
|
||||
import code.name.monkey.retromusic.util.LastFMUtil;
|
||||
import code.name.monkey.retromusic.util.MusicUtil;
|
||||
import code.name.monkey.retromusic.util.RetroUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
import retrofit2.Response;
|
||||
|
||||
|
||||
public class ArtistImageFetcher implements DataFetcher<InputStream> {
|
||||
public static final String TAG = ArtistImageFetcher.class.getSimpleName();
|
||||
private final LastFMRestClient lastFMRestClient;
|
||||
private final ArtistImage model;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private Context context;
|
||||
private ModelLoader<GlideUrl, InputStream> urlLoader;
|
||||
private volatile boolean isCancelled;
|
||||
private DataFetcher<InputStream> urlFetcher;
|
||||
|
||||
public ArtistImageFetcher(Context context, LastFMRestClient lastFMRestClient, ArtistImage model, ModelLoader<GlideUrl, InputStream> urlLoader, int width, int height) {
|
||||
this.context = context;
|
||||
this.lastFMRestClient = lastFMRestClient;
|
||||
this.model = model;
|
||||
this.urlLoader = urlLoader;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
// makes sure we never ever return null here
|
||||
return String.valueOf(model.artistName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream loadData(Priority priority) throws Exception {
|
||||
if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) {
|
||||
Response<LastFmArtist> response = lastFMRestClient.getApiService().getArtistInfo(model.artistName, null, model.skipOkHttpCache ? "no-cache" : null).execute();
|
||||
|
||||
if (!response.isSuccessful()) {
|
||||
throw new IOException("Request failed with code: " + response.code());
|
||||
}
|
||||
|
||||
LastFmArtist lastFmArtist = response.body();
|
||||
|
||||
if (isCancelled) return null;
|
||||
|
||||
GlideUrl url = new GlideUrl(LastFMUtil.getLargestArtistImageUrl(lastFmArtist.getArtist().getImage()));
|
||||
urlFetcher = urlLoader.getResourceFetcher(url, width, height);
|
||||
|
||||
return urlFetcher.loadData(priority);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
if (urlFetcher != null) {
|
||||
urlFetcher.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
isCancelled = true;
|
||||
if (urlFetcher != null) {
|
||||
urlFetcher.cancel();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package code.name.monkey.retromusic.glide.artistimage
|
||||
|
||||
import android.content.Context
|
||||
|
||||
import com.bumptech.glide.Priority
|
||||
import com.bumptech.glide.load.data.DataFetcher
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import com.bumptech.glide.load.model.ModelLoader
|
||||
import code.name.monkey.retromusic.rest.LastFMRestClient
|
||||
import code.name.monkey.retromusic.rest.model.LastFmArtist
|
||||
|
||||
import code.name.monkey.retromusic.util.LastFMUtil
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
import retrofit2.Response
|
||||
|
||||
|
||||
class ArtistImageFetcher(private val context: Context, private val lastFMRestClient: LastFMRestClient, private val model: ArtistImage, private val urlLoader: ModelLoader<GlideUrl, InputStream>, private val width: Int, private val height: Int) : DataFetcher<InputStream> {
|
||||
@Volatile
|
||||
private var isCancelled: Boolean = false
|
||||
private var urlFetcher: DataFetcher<InputStream>? = null
|
||||
|
||||
override fun getId(): String {
|
||||
// makes sure we never ever return null here
|
||||
return model.artistName
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun loadData(priority: Priority): InputStream? {
|
||||
if (!MusicUtil.isArtistNameUnknown(model.artistName) && RetroUtil.isAllowedToDownloadMetadata(context)) {
|
||||
val response = lastFMRestClient.apiService.getArtistInfo(model.artistName, null, if (model.skipOkHttpCache) "no-cache" else null).execute()
|
||||
|
||||
if (!response.isSuccessful) {
|
||||
throw IOException("Request failed with code: " + response.code())
|
||||
}
|
||||
|
||||
val lastFmArtist = response.body()
|
||||
|
||||
if (isCancelled) return null
|
||||
|
||||
val url = GlideUrl(LastFMUtil.getLargestArtistImageUrl(lastFmArtist!!.artist.image))
|
||||
urlFetcher = urlLoader.getResourceFetcher(url, width, height)
|
||||
|
||||
return urlFetcher!!.loadData(priority)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
if (urlFetcher != null) {
|
||||
urlFetcher!!.cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
isCancelled = true
|
||||
if (urlFetcher != null) {
|
||||
urlFetcher!!.cancel()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG = ArtistImageFetcher::class.java.simpleName
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.artistimage;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
import com.bumptech.glide.load.model.GenericLoaderFactory;
|
||||
import com.bumptech.glide.load.model.GlideUrl;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory;
|
||||
import com.bumptech.glide.load.model.stream.StreamModelLoader;
|
||||
import code.name.monkey.retromusic.rest.LastFMRestClient;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
|
||||
|
||||
|
||||
public class ArtistImageLoader implements StreamModelLoader<ArtistImage> {
|
||||
// we need these very low values to make sure our artist image loading calls doesn't block the image loading queue
|
||||
private static final int TIMEOUT = 500;
|
||||
|
||||
private Context context;
|
||||
private LastFMRestClient lastFMClient;
|
||||
private ModelLoader<GlideUrl, InputStream> urlLoader;
|
||||
|
||||
public ArtistImageLoader(Context context, LastFMRestClient lastFMRestClient, ModelLoader<GlideUrl, InputStream> urlLoader) {
|
||||
this.context = context;
|
||||
this.lastFMClient = lastFMRestClient;
|
||||
this.urlLoader = urlLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataFetcher<InputStream> getResourceFetcher(ArtistImage model, int width, int height) {
|
||||
return new ArtistImageFetcher(context, lastFMClient, model, urlLoader, width, height);
|
||||
}
|
||||
|
||||
public static class Factory implements ModelLoaderFactory<ArtistImage, InputStream> {
|
||||
private LastFMRestClient lastFMClient;
|
||||
private OkHttpUrlLoader.Factory okHttpFactory;
|
||||
|
||||
public Factory(Context context) {
|
||||
okHttpFactory = new OkHttpUrlLoader.Factory(new OkHttpClient.Builder()
|
||||
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.build());
|
||||
lastFMClient = new LastFMRestClient(LastFMRestClient.createDefaultOkHttpClientBuilder(context)
|
||||
.connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelLoader<ArtistImage, InputStream> build(Context context, GenericLoaderFactory factories) {
|
||||
return new ArtistImageLoader(context, lastFMClient, okHttpFactory.build(context, factories));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardown() {
|
||||
okHttpFactory.teardown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
package code.name.monkey.retromusic.glide.artistimage
|
||||
|
||||
import android.content.Context
|
||||
|
||||
import com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader
|
||||
import com.bumptech.glide.load.data.DataFetcher
|
||||
import com.bumptech.glide.load.model.GenericLoaderFactory
|
||||
import com.bumptech.glide.load.model.GlideUrl
|
||||
import com.bumptech.glide.load.model.ModelLoader
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory
|
||||
import com.bumptech.glide.load.model.stream.StreamModelLoader
|
||||
import code.name.monkey.retromusic.rest.LastFMRestClient
|
||||
|
||||
import java.io.InputStream
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import okhttp3.OkHttpClient
|
||||
|
||||
|
||||
class ArtistImageLoader(private val context: Context, private val lastFMClient: LastFMRestClient, private val urlLoader: ModelLoader<GlideUrl, InputStream>) : StreamModelLoader<ArtistImage> {
|
||||
|
||||
override fun getResourceFetcher(model: ArtistImage, width: Int, height: Int): DataFetcher<InputStream> {
|
||||
return ArtistImageFetcher(context, lastFMClient, model, urlLoader, width, height)
|
||||
}
|
||||
|
||||
class Factory(context: Context) : ModelLoaderFactory<ArtistImage, InputStream> {
|
||||
private val lastFMClient: LastFMRestClient = LastFMRestClient(LastFMRestClient.createDefaultOkHttpClientBuilder(context)
|
||||
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.build())
|
||||
private val okHttpFactory: OkHttpUrlLoader.Factory = OkHttpUrlLoader.Factory(OkHttpClient.Builder()
|
||||
.connectTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.readTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.writeTimeout(TIMEOUT.toLong(), TimeUnit.MILLISECONDS)
|
||||
.build())
|
||||
|
||||
override fun build(context: Context, factories: GenericLoaderFactory): ModelLoader<ArtistImage, InputStream> {
|
||||
return ArtistImageLoader(context, lastFMClient, okHttpFactory.build(context, factories))
|
||||
}
|
||||
|
||||
override fun teardown() {
|
||||
okHttpFactory.teardown()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// we need these very low values to make sure our artist image loading calls doesn't block the image loading queue
|
||||
private const val TIMEOUT = 500
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.audiocover;
|
||||
|
||||
|
||||
public class AudioFileCover {
|
||||
public final String filePath;
|
||||
|
||||
public AudioFileCover(String filePath) {
|
||||
this.filePath = filePath;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package code.name.monkey.retromusic.glide.audiocover
|
||||
|
||||
|
||||
class AudioFileCover(val filePath: String)
|
|
@ -1,95 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.audiocover;
|
||||
|
||||
import android.media.MediaMetadataRetriever;
|
||||
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException;
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException;
|
||||
import org.jaudiotagger.audio.mp3.MP3File;
|
||||
import org.jaudiotagger.tag.TagException;
|
||||
import org.jaudiotagger.tag.images.Artwork;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
public class AudioFileCoverFetcher implements DataFetcher<InputStream> {
|
||||
private static final String[] FALLBACKS = {"cover.jpg", "album.jpg", "folder.jpg", "cover.png", "album.png", "folder.png"};
|
||||
private final AudioFileCover model;
|
||||
private FileInputStream stream;
|
||||
|
||||
public AudioFileCoverFetcher(AudioFileCover model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
// makes sure we never ever return null here
|
||||
return String.valueOf(model.filePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream loadData(Priority priority) throws Exception {
|
||||
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
|
||||
try {
|
||||
retriever.setDataSource(model.filePath);
|
||||
byte[] picture = retriever.getEmbeddedPicture();
|
||||
if (picture != null) {
|
||||
return new ByteArrayInputStream(picture);
|
||||
} else {
|
||||
return fallback(model.filePath);
|
||||
}
|
||||
} finally {
|
||||
retriever.release();
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream fallback(String path) throws FileNotFoundException {
|
||||
// Method 1: use embedded high resolution album art if there is any
|
||||
try {
|
||||
MP3File mp3File = new MP3File(path);
|
||||
if (mp3File.hasID3v2Tag()) {
|
||||
Artwork art = mp3File.getTag().getFirstArtwork();
|
||||
if (art != null) {
|
||||
byte[] imageData = art.getBinaryData();
|
||||
return new ByteArrayInputStream(imageData);
|
||||
}
|
||||
}
|
||||
// If there are any exceptions, we ignore them and continue to the other fallback method
|
||||
} catch (ReadOnlyFileException | InvalidAudioFrameException | TagException | IOException ignored) {
|
||||
}
|
||||
|
||||
// Method 2: look for album art in external files
|
||||
File parent = new File(path).getParentFile();
|
||||
for (String fallback : FALLBACKS) {
|
||||
File cover = new File(parent, fallback);
|
||||
if (cover.exists()) {
|
||||
return stream = new FileInputStream(cover);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
// already cleaned up in loadData and ByteArrayInputStream will be GC'd
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream.close();
|
||||
} catch (IOException ignore) {
|
||||
// can't do much about it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
// cannot cancel
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package code.name.monkey.retromusic.glide.audiocover
|
||||
|
||||
import android.media.MediaMetadataRetriever
|
||||
import com.bumptech.glide.Priority
|
||||
import com.bumptech.glide.load.data.DataFetcher
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException
|
||||
import org.jaudiotagger.audio.mp3.MP3File
|
||||
import org.jaudiotagger.tag.TagException
|
||||
import java.io.*
|
||||
|
||||
|
||||
class AudioFileCoverFetcher(private val model: AudioFileCover) : DataFetcher<InputStream> {
|
||||
private var stream: FileInputStream? = null
|
||||
|
||||
override fun getId(): String {
|
||||
// makes sure we never ever return null here
|
||||
return model.filePath
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun loadData(priority: Priority): InputStream? {
|
||||
val retriever = MediaMetadataRetriever()
|
||||
try {
|
||||
retriever.setDataSource(model.filePath)
|
||||
val picture = retriever.embeddedPicture
|
||||
return if (picture != null) {
|
||||
ByteArrayInputStream(picture)
|
||||
} else {
|
||||
fallback(model.filePath)
|
||||
}
|
||||
} finally {
|
||||
retriever.release()
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(FileNotFoundException::class)
|
||||
private fun fallback(path: String): InputStream? {
|
||||
// Method 1: use embedded high resolution album art if there is any
|
||||
try {
|
||||
val mp3File = MP3File(path)
|
||||
if (mp3File.hasID3v2Tag()) {
|
||||
val art = mp3File.tag.firstArtwork
|
||||
if (art != null) {
|
||||
val imageData = art.binaryData
|
||||
return ByteArrayInputStream(imageData)
|
||||
}
|
||||
}
|
||||
// If there are any exceptions, we ignore them and continue to the other fallback method
|
||||
} catch (ignored: ReadOnlyFileException) {
|
||||
} catch (ignored: InvalidAudioFrameException) {
|
||||
} catch (ignored: TagException) {
|
||||
} catch (ignored: IOException) {
|
||||
}
|
||||
|
||||
// Method 2: look for album art in external files
|
||||
val parent = File(path).parentFile
|
||||
for (fallback in FALLBACKS) {
|
||||
val cover = File(parent, fallback)
|
||||
if (cover.exists()) {
|
||||
stream = FileInputStream(cover)
|
||||
return stream
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun cleanup() {
|
||||
// already cleaned up in loadData and ByteArrayInputStream will be GC'd
|
||||
if (stream != null) {
|
||||
try {
|
||||
stream!!.close()
|
||||
} catch (ignore: IOException) {
|
||||
// can't do much about it
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
// cannot cancel
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val FALLBACKS = arrayOf("cover.jpg", "album.jpg", "folder.jpg", "cover.png", "album.png", "folder.png")
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.audiocover;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
import com.bumptech.glide.load.model.GenericLoaderFactory;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory;
|
||||
import com.bumptech.glide.load.model.stream.StreamModelLoader;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
public class AudioFileCoverLoader implements StreamModelLoader<AudioFileCover> {
|
||||
|
||||
@Override
|
||||
public DataFetcher<InputStream> getResourceFetcher(AudioFileCover model, int width, int height) {
|
||||
return new AudioFileCoverFetcher(model);
|
||||
}
|
||||
|
||||
public static class Factory implements ModelLoaderFactory<AudioFileCover, InputStream> {
|
||||
@Override
|
||||
public ModelLoader<AudioFileCover, InputStream> build(Context context, GenericLoaderFactory factories) {
|
||||
return new AudioFileCoverLoader();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void teardown() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package code.name.monkey.retromusic.glide.audiocover
|
||||
|
||||
import android.content.Context
|
||||
|
||||
import com.bumptech.glide.load.data.DataFetcher
|
||||
import com.bumptech.glide.load.model.GenericLoaderFactory
|
||||
import com.bumptech.glide.load.model.ModelLoader
|
||||
import com.bumptech.glide.load.model.ModelLoaderFactory
|
||||
import com.bumptech.glide.load.model.stream.StreamModelLoader
|
||||
|
||||
import java.io.InputStream
|
||||
|
||||
|
||||
class AudioFileCoverLoader : StreamModelLoader<AudioFileCover> {
|
||||
|
||||
override fun getResourceFetcher(model: AudioFileCover, width: Int, height: Int): DataFetcher<InputStream> {
|
||||
return AudioFileCoverFetcher(model)
|
||||
}
|
||||
|
||||
class Factory : ModelLoaderFactory<AudioFileCover, InputStream> {
|
||||
override fun build(context: Context, factories: GenericLoaderFactory): ModelLoader<AudioFileCover, InputStream> {
|
||||
return AudioFileCoverLoader()
|
||||
}
|
||||
|
||||
override fun teardown() {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.palette;
|
||||
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
|
||||
import com.bumptech.glide.util.Util;
|
||||
|
||||
|
||||
public class BitmapPaletteResource implements Resource<BitmapPaletteWrapper> {
|
||||
|
||||
private final BitmapPaletteWrapper bitmapPaletteWrapper;
|
||||
private final BitmapPool bitmapPool;
|
||||
|
||||
public BitmapPaletteResource(BitmapPaletteWrapper bitmapPaletteWrapper, BitmapPool bitmapPool) {
|
||||
this.bitmapPaletteWrapper = bitmapPaletteWrapper;
|
||||
this.bitmapPool = bitmapPool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BitmapPaletteWrapper get() {
|
||||
return bitmapPaletteWrapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
return Util.getBitmapByteSize(bitmapPaletteWrapper.getBitmap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recycle() {
|
||||
if (!bitmapPool.put(bitmapPaletteWrapper.getBitmap())) {
|
||||
bitmapPaletteWrapper.getBitmap().recycle();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package code.name.monkey.retromusic.glide.palette
|
||||
|
||||
import com.bumptech.glide.load.engine.Resource
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
||||
import com.bumptech.glide.util.Util
|
||||
|
||||
|
||||
class BitmapPaletteResource(private val bitmapPaletteWrapper: BitmapPaletteWrapper, private val bitmapPool: BitmapPool) : Resource<BitmapPaletteWrapper> {
|
||||
|
||||
override fun get(): BitmapPaletteWrapper {
|
||||
return bitmapPaletteWrapper
|
||||
}
|
||||
|
||||
override fun getSize(): Int {
|
||||
return Util.getBitmapByteSize(bitmapPaletteWrapper.bitmap)
|
||||
}
|
||||
|
||||
override fun recycle() {
|
||||
if (!bitmapPool.put(bitmapPaletteWrapper.bitmap)) {
|
||||
bitmapPaletteWrapper.bitmap.recycle()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.palette;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
|
||||
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder;
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil;
|
||||
|
||||
public class BitmapPaletteTranscoder implements ResourceTranscoder<Bitmap, BitmapPaletteWrapper> {
|
||||
private final BitmapPool bitmapPool;
|
||||
|
||||
public BitmapPaletteTranscoder(Context context) {
|
||||
this(Glide.get(context).getBitmapPool());
|
||||
}
|
||||
|
||||
public BitmapPaletteTranscoder(BitmapPool bitmapPool) {
|
||||
this.bitmapPool = bitmapPool;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource<BitmapPaletteWrapper> transcode(Resource<Bitmap> bitmapResource) {
|
||||
Bitmap bitmap = bitmapResource.get();
|
||||
BitmapPaletteWrapper bitmapPaletteWrapper = new BitmapPaletteWrapper(bitmap, RetroColorUtil.generatePalette(bitmap));
|
||||
return new BitmapPaletteResource(bitmapPaletteWrapper, bitmapPool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "BitmapPaletteTranscoder.code.name.monkey.retromusic.glide.palette";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package code.name.monkey.retromusic.glide.palette
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.engine.Resource
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
||||
import com.bumptech.glide.load.resource.transcode.ResourceTranscoder
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
|
||||
class BitmapPaletteTranscoder(private val bitmapPool: BitmapPool) : ResourceTranscoder<Bitmap, BitmapPaletteWrapper> {
|
||||
|
||||
constructor(context: Context) : this(Glide.get(context).bitmapPool) {}
|
||||
|
||||
override fun transcode(bitmapResource: Resource<Bitmap>): Resource<BitmapPaletteWrapper> {
|
||||
val bitmap = bitmapResource.get()
|
||||
val bitmapPaletteWrapper = BitmapPaletteWrapper(bitmap, RetroColorUtil.generatePalette(bitmap)!!)
|
||||
return BitmapPaletteResource(bitmapPaletteWrapper, bitmapPool)
|
||||
}
|
||||
|
||||
override fun getId(): String {
|
||||
return "BitmapPaletteTranscoder.code.name.monkey.retromusic.glide.palette"
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
package code.name.monkey.retromusic.glide.palette;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import androidx.palette.graphics.Palette;
|
||||
|
||||
public class BitmapPaletteWrapper {
|
||||
private final Bitmap mBitmap;
|
||||
private final Palette mPalette;
|
||||
|
||||
public BitmapPaletteWrapper(Bitmap bitmap, Palette palette) {
|
||||
mBitmap = bitmap;
|
||||
mPalette = palette;
|
||||
}
|
||||
|
||||
public Bitmap getBitmap() {
|
||||
return mBitmap;
|
||||
}
|
||||
|
||||
public Palette getPalette() {
|
||||
return mPalette;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package code.name.monkey.retromusic.glide.palette
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import androidx.palette.graphics.Palette
|
||||
|
||||
class BitmapPaletteWrapper(val bitmap: Bitmap, val palette: Palette)
|
|
@ -1,12 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 09/08/17.
|
||||
*/
|
||||
|
||||
public interface BasePresenter<T> {
|
||||
|
||||
void subscribe();
|
||||
|
||||
void unsubscribe();
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package code.name.monkey.retromusic.mvp
|
||||
|
||||
/**
|
||||
* Created by hemanths on 09/08/17.
|
||||
*/
|
||||
|
||||
interface BasePresenter<T> {
|
||||
|
||||
fun subscribe()
|
||||
|
||||
fun unsubscribe()
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 09/08/17.
|
||||
*/
|
||||
|
||||
public interface BaseView<T> {
|
||||
void loading();
|
||||
|
||||
void showData(T list);
|
||||
|
||||
void showEmptyView();
|
||||
|
||||
void completed();
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package code.name.monkey.retromusic.mvp
|
||||
|
||||
/**
|
||||
* Created by hemanths on 09/08/17.
|
||||
*/
|
||||
|
||||
interface BaseView<T> {
|
||||
fun loading()
|
||||
|
||||
fun showData(list: T)
|
||||
|
||||
fun showEmptyView()
|
||||
|
||||
fun completed()
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import code.name.monkey.retromusic.Injection;
|
||||
import code.name.monkey.retromusic.providers.interfaces.Repository;
|
||||
import code.name.monkey.retromusic.util.schedulers.BaseSchedulerProvider;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 16/08/17.
|
||||
*/
|
||||
|
||||
public class Presenter {
|
||||
@NonNull
|
||||
protected Repository repository;
|
||||
@NonNull
|
||||
protected CompositeDisposable disposable;
|
||||
@NonNull
|
||||
protected BaseSchedulerProvider schedulerProvider;
|
||||
|
||||
public Presenter() {
|
||||
this.repository = Injection.INSTANCE.provideRepository();
|
||||
this.schedulerProvider = Injection.INSTANCE.provideSchedulerProvider();
|
||||
this.disposable = new CompositeDisposable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package code.name.monkey.retromusic.mvp
|
||||
|
||||
import code.name.monkey.retromusic.Injection
|
||||
import code.name.monkey.retromusic.providers.interfaces.Repository
|
||||
import code.name.monkey.retromusic.util.schedulers.BaseSchedulerProvider
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
||||
/**
|
||||
* Created by hemanths on 16/08/17.
|
||||
*/
|
||||
|
||||
open class Presenter {
|
||||
protected var repository: Repository = Injection.provideRepository()
|
||||
protected var disposable: CompositeDisposable = CompositeDisposable()
|
||||
protected var schedulerProvider: BaseSchedulerProvider = Injection.provideSchedulerProvider()
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public interface AlbumContract {
|
||||
|
||||
interface AlbumView extends BaseView<ArrayList<Album>> {
|
||||
|
||||
}
|
||||
|
||||
interface Presenter extends BasePresenter<AlbumView> {
|
||||
|
||||
void loadAlbums();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
import java.util.ArrayList
|
||||
|
||||
interface AlbumContract {
|
||||
|
||||
interface AlbumView : BaseView<ArrayList<Album>>
|
||||
|
||||
interface Presenter : BasePresenter<AlbumView> {
|
||||
|
||||
fun loadAlbums()
|
||||
}
|
||||
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
|
||||
public interface AlbumDetailsContract {
|
||||
|
||||
interface AlbumDetailsView extends BaseView<Album> {
|
||||
|
||||
}
|
||||
|
||||
interface Presenter extends BasePresenter<AlbumDetailsView> {
|
||||
|
||||
void loadAlbumSongs(int albumId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
|
||||
interface AlbumDetailsContract {
|
||||
|
||||
interface AlbumDetailsView : BaseView<Album>
|
||||
|
||||
interface Presenter : BasePresenter<AlbumDetailsView> {
|
||||
|
||||
fun loadAlbumSongs(albumId: Int)
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 16/08/17.
|
||||
*/
|
||||
|
||||
public interface ArtistContract {
|
||||
interface ArtistView extends BaseView<ArrayList<Artist>> {
|
||||
|
||||
}
|
||||
|
||||
interface Presenter extends BasePresenter<ArtistView> {
|
||||
void loadArtists();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 16/08/17.
|
||||
*/
|
||||
|
||||
interface ArtistContract {
|
||||
interface ArtistView : BaseView<ArrayList<Artist>>
|
||||
|
||||
interface Presenter : BasePresenter<ArtistView> {
|
||||
fun loadArtists()
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
public interface ArtistDetailContract {
|
||||
interface ArtistsDetailsView extends BaseView<Artist> {
|
||||
|
||||
}
|
||||
|
||||
interface Presenter extends BasePresenter<ArtistsDetailsView> {
|
||||
void loadArtistById();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
interface ArtistDetailContract {
|
||||
interface ArtistsDetailsView : BaseView<Artist>
|
||||
|
||||
interface Presenter : BasePresenter<ArtistsDetailsView> {
|
||||
fun loadArtistById()
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public interface GenreContract {
|
||||
interface GenreView extends BaseView<ArrayList<Genre>> {
|
||||
|
||||
}
|
||||
|
||||
interface Presenter extends BasePresenter<GenreView> {
|
||||
void loadGenre();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
import code.name.monkey.retromusic.model.Genre
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
interface GenreContract {
|
||||
interface GenreView : BaseView<ArrayList<Genre>>
|
||||
|
||||
interface Presenter : BasePresenter<GenreView> {
|
||||
fun loadGenre()
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public interface GenreDetailsContract {
|
||||
interface GenreDetailsView extends BaseView<ArrayList<Song>> {
|
||||
}
|
||||
|
||||
interface Presenter extends BasePresenter<GenreDetailsView> {
|
||||
void loadGenre(int genreId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
interface GenreDetailsContract {
|
||||
interface GenreDetailsView : BaseView<ArrayList<Song>>
|
||||
|
||||
interface Presenter : BasePresenter<GenreDetailsView> {
|
||||
fun loadGenre(genreId: Int)
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
|
||||
public interface HomeContract {
|
||||
|
||||
interface HomeView extends BaseView<ArrayList<Object>> {
|
||||
|
||||
void recentArtist(ArrayList<Artist> artists);
|
||||
|
||||
void recentAlbum(ArrayList<Album> albums);
|
||||
|
||||
void topArtists(ArrayList<Artist> artists);
|
||||
|
||||
void topAlbums(ArrayList<Album> albums);
|
||||
|
||||
void suggestions(ArrayList<Song> songs);
|
||||
|
||||
void playlists(ArrayList<Playlist> playlists);
|
||||
|
||||
void geners(ArrayList<Genre> songs);
|
||||
}
|
||||
|
||||
interface HomePresenter extends BasePresenter<HomeView> {
|
||||
|
||||
void loadRecentAlbums();
|
||||
|
||||
void loadTopAlbums();
|
||||
|
||||
void loadRecentArtists();
|
||||
|
||||
void loadTopArtists();
|
||||
|
||||
void loadSuggestions();
|
||||
|
||||
void loadGenres();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.model.Genre
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
|
||||
interface HomeContract {
|
||||
|
||||
interface HomeView : BaseView<ArrayList<Any>> {
|
||||
|
||||
fun recentArtist(artists: ArrayList<Artist>)
|
||||
|
||||
fun recentAlbum(albums: ArrayList<Album>)
|
||||
|
||||
fun topArtists(artists: ArrayList<Artist>)
|
||||
|
||||
fun topAlbums(albums: ArrayList<Album>)
|
||||
|
||||
fun suggestions(songs: ArrayList<Song>)
|
||||
|
||||
fun playlists(playlists: ArrayList<Playlist>)
|
||||
|
||||
fun geners(songs: ArrayList<Genre>)
|
||||
}
|
||||
|
||||
interface HomePresenter : BasePresenter<HomeView> {
|
||||
|
||||
fun loadRecentAlbums()
|
||||
|
||||
fun loadTopAlbums()
|
||||
|
||||
fun loadRecentArtists()
|
||||
|
||||
fun loadTopArtists()
|
||||
|
||||
fun loadSuggestions()
|
||||
|
||||
fun loadGenres()
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 19/08/17.
|
||||
*/
|
||||
|
||||
public interface PlaylistContract {
|
||||
interface PlaylistView extends BaseView<ArrayList<Playlist> > {
|
||||
|
||||
}
|
||||
|
||||
interface Presenter extends BasePresenter<PlaylistView> {
|
||||
void loadPlaylists();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* Created by hemanths on 19/08/17.
|
||||
*/
|
||||
|
||||
interface PlaylistContract {
|
||||
interface PlaylistView : BaseView<ArrayList<Playlist>>
|
||||
|
||||
interface Presenter : BasePresenter<PlaylistView> {
|
||||
fun loadPlaylists()
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
public interface PlaylistSongsContract {
|
||||
interface PlaylistSongsView extends BaseView<ArrayList<Song>> {
|
||||
|
||||
}
|
||||
|
||||
interface Presenter extends BasePresenter<PlaylistSongsView> {
|
||||
void loadSongs(Playlist playlist);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
interface PlaylistSongsContract {
|
||||
interface PlaylistSongsView : BaseView<ArrayList<Song>>
|
||||
|
||||
interface Presenter : BasePresenter<PlaylistSongsView> {
|
||||
fun loadSongs(playlist: Playlist)
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
public interface SearchContract {
|
||||
interface SearchView extends BaseView<ArrayList<Object>> {
|
||||
|
||||
}
|
||||
|
||||
interface SearchPresenter extends BasePresenter<SearchView> {
|
||||
void search(String query);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
interface SearchContract {
|
||||
interface SearchView : BaseView<ArrayList<Any>>
|
||||
|
||||
interface SearchPresenter : BasePresenter<SearchView> {
|
||||
fun search(query: String)
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.contract;
|
||||
|
||||
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter;
|
||||
import code.name.monkey.retromusic.mvp.BaseView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 10/08/17.
|
||||
*/
|
||||
|
||||
public interface SongContract {
|
||||
|
||||
interface SongView extends BaseView<ArrayList<Song>> {
|
||||
|
||||
}
|
||||
|
||||
interface Presenter extends BasePresenter<SongView> {
|
||||
void loadSongs();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package code.name.monkey.retromusic.mvp.contract
|
||||
|
||||
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.mvp.BasePresenter
|
||||
import code.name.monkey.retromusic.mvp.BaseView
|
||||
|
||||
import java.util.ArrayList
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 10/08/17.
|
||||
*/
|
||||
|
||||
interface SongContract {
|
||||
|
||||
interface SongView : BaseView<ArrayList<Song>>
|
||||
|
||||
interface Presenter : BasePresenter<SongView> {
|
||||
fun loadSongs()
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.AlbumDetailsContract;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
public class AlbumDetailsPresenter extends Presenter implements AlbumDetailsContract.Presenter {
|
||||
|
||||
@NonNull
|
||||
private final int albumId;
|
||||
@NonNull
|
||||
private AlbumDetailsContract.AlbumDetailsView view;
|
||||
|
||||
public AlbumDetailsPresenter(@NonNull AlbumDetailsContract.AlbumDetailsView view, int albumId) {
|
||||
|
||||
this.view = view;
|
||||
this.albumId = albumId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
loadAlbumSongs(albumId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadAlbumSongs(int albumId) {
|
||||
disposable.add(repository.getAlbum(albumId)
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(this::showAlbum,
|
||||
throwable -> view.showEmptyView(),
|
||||
() -> view.completed()));
|
||||
}
|
||||
|
||||
private void showAlbum(Album album) {
|
||||
if (album != null) {
|
||||
view.showData(album);
|
||||
} else {
|
||||
view.showEmptyView();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.AlbumDetailsContract
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
class AlbumDetailsPresenter(private val view: AlbumDetailsContract.AlbumDetailsView, private val albumId: Int) : Presenter(), AlbumDetailsContract.Presenter {
|
||||
|
||||
override fun subscribe() {
|
||||
loadAlbumSongs(albumId)
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
override fun loadAlbumSongs(albumId: Int) {
|
||||
disposable.add(repository.getAlbum(albumId)
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ this.showAlbum(it) },
|
||||
{ view.showEmptyView() },
|
||||
{ view.completed() }))
|
||||
}
|
||||
|
||||
private fun showAlbum(album: Album?) {
|
||||
if (album != null) {
|
||||
view.showData(album)
|
||||
} else {
|
||||
view.showEmptyView()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.AlbumContract;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 12/08/17.
|
||||
*/
|
||||
|
||||
public class AlbumPresenter extends Presenter implements AlbumContract.Presenter {
|
||||
@NonNull
|
||||
private AlbumContract.AlbumView view;
|
||||
|
||||
|
||||
public AlbumPresenter(@NonNull AlbumContract.AlbumView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
loadAlbums();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
private void showList(@NonNull ArrayList<Album> albums) {
|
||||
view.showData(albums);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadAlbums() {
|
||||
disposable.add(repository.getAllAlbums()
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(this::showList,
|
||||
throwable -> view.showEmptyView(),
|
||||
() -> view.completed()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.model.Album
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.AlbumContract
|
||||
import java.util.*
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 12/08/17.
|
||||
*/
|
||||
|
||||
class AlbumPresenter(private val view: AlbumContract.AlbumView) : Presenter(), AlbumContract.Presenter {
|
||||
|
||||
override fun subscribe() {
|
||||
loadAlbums()
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
private fun showList(albums: ArrayList<Album>) {
|
||||
view.showData(albums)
|
||||
}
|
||||
|
||||
override fun loadAlbums() {
|
||||
disposable.add(repository.allAlbums
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ this.showList(it) },
|
||||
{ view.showEmptyView() },
|
||||
{ view.completed() }))
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.ArtistDetailContract;
|
||||
import code.name.monkey.retromusic.ui.activities.ArtistDetailActivity;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
public class ArtistDetailsPresenter extends Presenter implements ArtistDetailContract.Presenter {
|
||||
|
||||
@NonNull
|
||||
private final ArtistDetailContract.ArtistsDetailsView view;
|
||||
private Bundle bundle;
|
||||
|
||||
public ArtistDetailsPresenter(@NonNull ArtistDetailContract.ArtistsDetailsView view,
|
||||
Bundle artistId) {
|
||||
this.view = view;
|
||||
this.bundle = artistId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
loadArtistById();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadArtistById() {
|
||||
disposable.add(repository.getArtistById(bundle.getInt(ArtistDetailActivity.EXTRA_ARTIST_ID))
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(this::showArtist,
|
||||
throwable -> view.showEmptyView(),
|
||||
view::completed));
|
||||
}
|
||||
|
||||
private void showArtist(Artist album) {
|
||||
if (album != null) {
|
||||
view.showData(album);
|
||||
} else {
|
||||
view.showEmptyView();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import android.os.Bundle
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.ArtistDetailContract
|
||||
import code.name.monkey.retromusic.ui.activities.ArtistDetailActivity
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
class ArtistDetailsPresenter(private val view: ArtistDetailContract.ArtistsDetailsView,
|
||||
private val bundle: Bundle) : Presenter(), ArtistDetailContract.Presenter {
|
||||
|
||||
override fun subscribe() {
|
||||
loadArtistById()
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
override fun loadArtistById() {
|
||||
disposable.add(repository.getArtistById(bundle.getInt(ArtistDetailActivity.EXTRA_ARTIST_ID).toLong())
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ this.showArtist(it) },
|
||||
{ view.showEmptyView() },
|
||||
{ view.completed() }))
|
||||
}
|
||||
|
||||
private fun showArtist(album: Artist?) {
|
||||
if (album != null) {
|
||||
view.showData(album)
|
||||
} else {
|
||||
view.showEmptyView()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.ArtistContract;
|
||||
|
||||
public class ArtistPresenter extends Presenter implements ArtistContract.Presenter {
|
||||
@NonNull
|
||||
private ArtistContract.ArtistView mView;
|
||||
|
||||
public ArtistPresenter(@NonNull ArtistContract.ArtistView view) {
|
||||
mView = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
loadArtists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
private void showList(@NonNull ArrayList<Artist> songs) {
|
||||
if (songs.isEmpty()) {
|
||||
mView.showEmptyView();
|
||||
} else {
|
||||
mView.showData(songs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadArtists() {
|
||||
disposable.add(repository.getAllArtists()
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe(disposable1 -> mView.loading())
|
||||
.subscribe(this::showList,
|
||||
throwable -> mView.showEmptyView(),
|
||||
() -> mView.completed()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.model.Artist
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.ArtistContract
|
||||
import java.util.*
|
||||
|
||||
class ArtistPresenter(private val mView: ArtistContract.ArtistView) : Presenter(), ArtistContract.Presenter {
|
||||
|
||||
override fun subscribe() {
|
||||
loadArtists()
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
private fun showList(songs: ArrayList<Artist>) {
|
||||
if (songs.isEmpty()) {
|
||||
mView.showEmptyView()
|
||||
} else {
|
||||
mView.showData(songs)
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadArtists() {
|
||||
disposable.add(repository.allArtists
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe { mView.loading() }
|
||||
.subscribe({ this.showList(it) },
|
||||
{ mView.showEmptyView() },
|
||||
{ mView.completed() }))
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.GenreDetailsContract;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
public class GenreDetailsPresenter extends Presenter
|
||||
implements GenreDetailsContract.Presenter {
|
||||
private final int genreId;
|
||||
@NonNull
|
||||
private GenreDetailsContract.GenreDetailsView view;
|
||||
|
||||
public GenreDetailsPresenter(@NonNull GenreDetailsContract.GenreDetailsView view,
|
||||
int genreId) {
|
||||
this.view = view;
|
||||
this.genreId = genreId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
loadGenre(genreId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadGenre(int genreId) {
|
||||
disposable.add(repository.getGenre(genreId)
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(this::showGenre,
|
||||
throwable -> view.showEmptyView(),
|
||||
() -> view.completed()));
|
||||
}
|
||||
|
||||
private void showGenre(ArrayList<Song> songs) {
|
||||
if (songs != null) {
|
||||
view.showData(songs);
|
||||
} else {
|
||||
view.showEmptyView();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.GenreDetailsContract
|
||||
import java.util.*
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
class GenreDetailsPresenter(private val view: GenreDetailsContract.GenreDetailsView,
|
||||
private val genreId: Int) : Presenter(), GenreDetailsContract.Presenter {
|
||||
|
||||
override fun subscribe() {
|
||||
loadGenre(genreId)
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
override fun loadGenre(genreId: Int) {
|
||||
disposable.add(repository.getGenre(genreId)
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ this.showGenre(it) },
|
||||
{ view.showEmptyView() },
|
||||
{ view.completed() }))
|
||||
}
|
||||
|
||||
private fun showGenre(songs: ArrayList<Song>?) {
|
||||
if (songs != null) {
|
||||
view.showData(songs)
|
||||
} else {
|
||||
view.showEmptyView()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.GenreContract;
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
public class GenrePresenter extends Presenter
|
||||
implements GenreContract.Presenter {
|
||||
@NonNull
|
||||
private GenreContract.GenreView view;
|
||||
|
||||
public GenrePresenter(
|
||||
@NonNull GenreContract.GenreView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
loadGenre();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadGenre() {
|
||||
disposable.add(repository.getAllGenres()
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(this::showList,
|
||||
throwable -> view.showEmptyView(),
|
||||
() -> view.completed()));
|
||||
}
|
||||
|
||||
private void showList(@NonNull ArrayList<Genre> genres) {
|
||||
if (genres.isEmpty()) {
|
||||
view.showEmptyView();
|
||||
} else {
|
||||
view.showData(genres);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.model.Genre
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.GenreContract
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
|
||||
class GenrePresenter(
|
||||
private val view: GenreContract.GenreView) : Presenter(), GenreContract.Presenter {
|
||||
|
||||
override fun subscribe() {
|
||||
loadGenre()
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
override fun loadGenre() {
|
||||
disposable.add(repository.allGenres
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ this.showList(it) },
|
||||
{ view.showEmptyView() },
|
||||
{ view.completed() }))
|
||||
}
|
||||
|
||||
private fun showList(genres: ArrayList<Genre>) {
|
||||
if (genres.isEmpty()) {
|
||||
view.showEmptyView()
|
||||
} else {
|
||||
view.showData(genres)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.HomeContract;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
|
||||
public class HomePresenter extends Presenter implements HomeContract.HomePresenter {
|
||||
|
||||
@NonNull
|
||||
private HomeContract.HomeView view;
|
||||
|
||||
public HomePresenter(@NonNull HomeContract.HomeView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
|
||||
loadRecentAlbums();
|
||||
loadRecentArtists();
|
||||
loadTopAlbums();
|
||||
loadTopArtists();
|
||||
loadSuggestions();
|
||||
|
||||
if (PreferenceUtil.getInstance().isGenreShown()) loadGenres();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
public void loadPlaylists() {
|
||||
disposable.add(repository.getAllPlaylists()
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.subscribe(playlist -> {
|
||||
if (!playlist.isEmpty()) {
|
||||
view.playlists(playlist);
|
||||
}
|
||||
},
|
||||
throwable -> view.showEmptyView(), () -> view.completed()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadRecentAlbums() {
|
||||
disposable.add(repository.getRecentAlbums()
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(artists -> {
|
||||
if (!artists.isEmpty()) {
|
||||
view.recentAlbum(artists);
|
||||
}
|
||||
},
|
||||
throwable -> view.showEmptyView(), () -> view.completed()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadTopAlbums() {
|
||||
disposable.add(repository.getTopAlbums()
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(artists -> {
|
||||
if (!artists.isEmpty()) {
|
||||
view.topAlbums(artists);
|
||||
}
|
||||
},
|
||||
throwable -> view.showEmptyView(), () -> view.completed()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadRecentArtists() {
|
||||
disposable.add(repository.getRecentArtists()
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(artists -> {
|
||||
if (!artists.isEmpty()) {
|
||||
view.recentArtist(artists);
|
||||
}
|
||||
},
|
||||
throwable -> view.showEmptyView(), () -> view.completed()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadTopArtists() {
|
||||
disposable.add(repository.getTopArtists()
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(artists -> {
|
||||
if (!artists.isEmpty()) {
|
||||
view.topArtists(artists);
|
||||
}
|
||||
},
|
||||
throwable -> view.showEmptyView(), () -> view.completed()));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSuggestions() {
|
||||
disposable.add(repository.getSuggestionSongs()
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(songs -> view.suggestions(songs), throwable -> view.showEmptyView(), () -> view.completed()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadGenres() {
|
||||
disposable.add(repository.getAllGenres()
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(genres -> {
|
||||
if (!genres.isEmpty()) {
|
||||
view.geners(genres);
|
||||
}
|
||||
},
|
||||
throwable -> view.showEmptyView(), () -> view.completed()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.HomeContract
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
|
||||
class HomePresenter(private val view: HomeContract.HomeView) : Presenter(), HomeContract.HomePresenter {
|
||||
|
||||
override fun subscribe() {
|
||||
|
||||
loadRecentAlbums()
|
||||
loadRecentArtists()
|
||||
loadTopAlbums()
|
||||
loadTopArtists()
|
||||
loadSuggestions()
|
||||
|
||||
if (PreferenceUtil.getInstance().isGenreShown) loadGenres()
|
||||
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
fun loadPlaylists() {
|
||||
disposable.add(repository.allPlaylists
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.subscribe({ playlist ->
|
||||
if (!playlist.isEmpty()) {
|
||||
view.playlists(playlist)
|
||||
}
|
||||
}, { view.showEmptyView() }, { view.completed() }))
|
||||
}
|
||||
|
||||
override fun loadRecentAlbums() {
|
||||
disposable.add(repository.recentAlbums
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ artists ->
|
||||
if (!artists.isEmpty()) {
|
||||
view.recentAlbum(artists)
|
||||
}
|
||||
}, { view.showEmptyView() }, { view.completed() }))
|
||||
}
|
||||
|
||||
override fun loadTopAlbums() {
|
||||
disposable.add(repository.topAlbums
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ artists ->
|
||||
if (!artists.isEmpty()) {
|
||||
view.topAlbums(artists)
|
||||
}
|
||||
}, { view.showEmptyView() }, { view.completed() }))
|
||||
}
|
||||
|
||||
override fun loadRecentArtists() {
|
||||
disposable.add(repository.recentArtists
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ artists ->
|
||||
if (!artists.isEmpty()) {
|
||||
view.recentArtist(artists)
|
||||
}
|
||||
}, { view.showEmptyView() }, { view.completed() }))
|
||||
}
|
||||
|
||||
override fun loadTopArtists() {
|
||||
disposable.add(repository.topArtists
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ artists ->
|
||||
if (!artists.isEmpty()) {
|
||||
view.topArtists(artists)
|
||||
}
|
||||
}, { view.showEmptyView() }, { view.completed() }))
|
||||
|
||||
}
|
||||
|
||||
override fun loadSuggestions() {
|
||||
disposable.add(repository.suggestionSongs
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ songs -> view.suggestions(songs) }, { view.showEmptyView() }, { view.completed() }))
|
||||
}
|
||||
|
||||
override fun loadGenres() {
|
||||
disposable.add(repository.allGenres
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ genres ->
|
||||
if (!genres.isEmpty()) {
|
||||
view.geners(genres)
|
||||
}
|
||||
},
|
||||
{ view.showEmptyView() }, { view.completed() }))
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.PlaylistContract;
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 19/08/17.
|
||||
*/
|
||||
|
||||
public class PlaylistPresenter extends Presenter
|
||||
implements PlaylistContract.Presenter {
|
||||
@NonNull
|
||||
private PlaylistContract.PlaylistView mView;
|
||||
|
||||
public PlaylistPresenter(@NonNull PlaylistContract.PlaylistView view) {
|
||||
|
||||
mView = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
loadPlaylists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadPlaylists() {
|
||||
disposable.add(repository.getAllPlaylists()
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe(disposable1 -> mView.loading())
|
||||
.subscribe(this::showList,
|
||||
throwable -> mView.showEmptyView(),
|
||||
() -> mView.completed()));
|
||||
}
|
||||
|
||||
private void showList(@NonNull ArrayList<Playlist> songs) {
|
||||
if (songs.isEmpty()) {
|
||||
mView.showEmptyView();
|
||||
} else {
|
||||
mView.showData(songs);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.PlaylistContract
|
||||
import java.util.*
|
||||
|
||||
|
||||
/**
|
||||
* Created by hemanths on 19/08/17.
|
||||
*/
|
||||
|
||||
class PlaylistPresenter(private val view: PlaylistContract.PlaylistView) : Presenter(), PlaylistContract.Presenter {
|
||||
|
||||
override fun subscribe() {
|
||||
loadPlaylists()
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
override fun loadPlaylists() {
|
||||
disposable.add(repository.allPlaylists
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ this.showList(it) },
|
||||
{ view.showEmptyView() },
|
||||
{ view.completed() }))
|
||||
}
|
||||
|
||||
private fun showList(songs: ArrayList<Playlist>) {
|
||||
if (songs.isEmpty()) {
|
||||
view.showEmptyView()
|
||||
} else {
|
||||
view.showData(songs)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.PlaylistSongsContract;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
public class PlaylistSongsPresenter extends Presenter
|
||||
implements PlaylistSongsContract.Presenter {
|
||||
@NonNull
|
||||
private PlaylistSongsContract.PlaylistSongsView mView;
|
||||
@NonNull
|
||||
private Playlist mPlaylist;
|
||||
|
||||
public PlaylistSongsPresenter(@NonNull PlaylistSongsContract.PlaylistSongsView view,
|
||||
@NonNull Playlist playlist) {
|
||||
|
||||
mView = view;
|
||||
mPlaylist = playlist;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
loadSongs(mPlaylist);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSongs(Playlist playlist) {
|
||||
disposable.add(repository.getPlaylistSongs(playlist)
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe(disposable1 -> mView.loading())
|
||||
.subscribe(songs -> mView.showData(songs),
|
||||
throwable -> mView.showEmptyView(),
|
||||
() -> mView.completed()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.PlaylistSongsContract
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
class PlaylistSongsPresenter(private val view: PlaylistSongsContract.PlaylistSongsView,
|
||||
private val mPlaylist: Playlist) : Presenter(), PlaylistSongsContract.Presenter {
|
||||
|
||||
|
||||
override fun subscribe() {
|
||||
loadSongs(mPlaylist)
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
override fun loadSongs(playlist: Playlist) {
|
||||
disposable.add(repository.getPlaylistSongs(playlist)
|
||||
.subscribeOn(schedulerProvider.io())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ songs -> view.showData(songs) },
|
||||
{ view.showEmptyView() },
|
||||
{ view.completed() }))
|
||||
}
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.SearchContract;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
public class SearchPresenter extends Presenter implements SearchContract.SearchPresenter {
|
||||
@NonNull
|
||||
private SearchContract.SearchView mView;
|
||||
|
||||
public SearchPresenter(@NonNull SearchContract.SearchView view) {
|
||||
mView = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
search("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
|
||||
private void showList(@NonNull ArrayList<Object> albums) {
|
||||
if (albums.isEmpty()) {
|
||||
mView.showEmptyView();
|
||||
} else {
|
||||
mView.showData(albums);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void search(String query) {
|
||||
disposable.add(repository.search(query)
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe(disposable1 -> mView.loading())
|
||||
.subscribe(this::showList,
|
||||
throwable -> mView.showEmptyView(),
|
||||
() -> mView.completed()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.SearchContract
|
||||
import java.util.*
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
/**
|
||||
* Created by hemanths on 20/08/17.
|
||||
*/
|
||||
|
||||
class SearchPresenter(private val view: SearchContract.SearchView) : Presenter(), SearchContract.SearchPresenter {
|
||||
|
||||
override fun subscribe() {
|
||||
search("")
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
|
||||
private fun showList(albums: ArrayList<Any>) {
|
||||
if (albums.isEmpty()) {
|
||||
view.showEmptyView()
|
||||
} else {
|
||||
view.showData(albums)
|
||||
}
|
||||
}
|
||||
|
||||
override fun search(query: String) {
|
||||
disposable.add(repository.search(query)
|
||||
.debounce(500, TimeUnit.MILLISECONDS)
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ this.showList(it) },
|
||||
{ view.showEmptyView() },
|
||||
{ view.completed() }))
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.mvp.Presenter;
|
||||
import code.name.monkey.retromusic.mvp.contract.SongContract;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 10/08/17.
|
||||
*/
|
||||
|
||||
public class SongPresenter extends Presenter implements SongContract.Presenter {
|
||||
|
||||
@NonNull
|
||||
private SongContract.SongView view;
|
||||
|
||||
|
||||
public SongPresenter(@NonNull SongContract.SongView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSongs() {
|
||||
disposable.add(repository.getAllSongs()
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe(disposable1 -> view.loading())
|
||||
.subscribe(this::showList,
|
||||
throwable -> view.showEmptyView(),
|
||||
() -> view.completed()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subscribe() {
|
||||
loadSongs();
|
||||
}
|
||||
|
||||
private void showList(@NonNull ArrayList<Song> songs) {
|
||||
if (songs.isEmpty()) {
|
||||
view.showEmptyView();
|
||||
} else {
|
||||
view.showData(songs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unsubscribe() {
|
||||
disposable.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package code.name.monkey.retromusic.mvp.presenter
|
||||
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.mvp.Presenter
|
||||
import code.name.monkey.retromusic.mvp.contract.SongContract
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* Created by hemanths on 10/08/17.
|
||||
*/
|
||||
|
||||
class SongPresenter(private val view: SongContract.SongView) : Presenter(), SongContract.Presenter {
|
||||
|
||||
override fun loadSongs() {
|
||||
disposable.add(repository.allSongs
|
||||
.subscribeOn(schedulerProvider.computation())
|
||||
.observeOn(schedulerProvider.ui())
|
||||
.doOnSubscribe { view.loading() }
|
||||
.subscribe({ this.showList(it) },
|
||||
{ view.showEmptyView() },
|
||||
{ view.completed() }))
|
||||
}
|
||||
|
||||
override fun subscribe() {
|
||||
loadSongs()
|
||||
}
|
||||
|
||||
private fun showList(songs: ArrayList<Song>) {
|
||||
if (songs.isEmpty()) {
|
||||
view.showEmptyView()
|
||||
} else {
|
||||
view.showData(songs)
|
||||
}
|
||||
}
|
||||
|
||||
override fun unsubscribe() {
|
||||
disposable.clear()
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package code.name.monkey.retromusic.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference;
|
||||
|
||||
|
||||
public class AlbumCoverStylePreference extends ATEDialogPreference {
|
||||
public AlbumCoverStylePreference(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public AlbumCoverStylePreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public AlbumCoverStylePreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public AlbumCoverStylePreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package code.name.monkey.retromusic.preferences
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference
|
||||
|
||||
|
||||
class AlbumCoverStylePreference : ATEDialogPreference {
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
|
||||
}
|
|
@ -1,137 +0,0 @@
|
|||
package code.name.monkey.retromusic.preferences;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.ui.fragments.AlbumCoverStyle;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
||||
|
||||
public class AlbumCoverStylePreferenceDialog extends DialogFragment implements
|
||||
ViewPager.OnPageChangeListener, MaterialDialog.SingleButtonCallback {
|
||||
public static final String TAG = AlbumCoverStylePreferenceDialog.class.getSimpleName();
|
||||
|
||||
private DialogAction whichButtonClicked;
|
||||
private int viewPagerPosition;
|
||||
|
||||
public static AlbumCoverStylePreferenceDialog newInstance() {
|
||||
return new AlbumCoverStylePreferenceDialog();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
@SuppressLint("InflateParams") View view = LayoutInflater.from(getActivity()).inflate(R.layout.preference_dialog_now_playing_screen, null);
|
||||
ViewPager viewPager = view.findViewById(R.id.now_playing_screen_view_pager);
|
||||
viewPager.setAdapter(new AlbumCoverStyleAdapter(getActivity()));
|
||||
viewPager.addOnPageChangeListener(this);
|
||||
viewPager.setPageMargin((int) ViewUtil.convertDpToPixel(32, getResources()));
|
||||
viewPager.setCurrentItem(PreferenceUtil.getInstance().getAlbumCoverStyle().ordinal());
|
||||
|
||||
return new MaterialDialog.Builder(getActivity())
|
||||
.title(R.string.pref_title_album_cover_style)
|
||||
.positiveText(android.R.string.ok)
|
||||
.negativeText(android.R.string.cancel)
|
||||
.onAny(this)
|
||||
.customView(view, false)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog,
|
||||
@NonNull DialogAction which) {
|
||||
whichButtonClicked = which;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
if (whichButtonClicked == DialogAction.POSITIVE) {
|
||||
AlbumCoverStyle nowPlayingScreen = AlbumCoverStyle.values()[viewPagerPosition];
|
||||
PreferenceUtil.getInstance().setAlbumCoverStyle(nowPlayingScreen);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
this.viewPagerPosition = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
|
||||
}
|
||||
|
||||
private static class AlbumCoverStyleAdapter extends PagerAdapter {
|
||||
|
||||
private Context context;
|
||||
|
||||
AlbumCoverStyleAdapter(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Object instantiateItem(@NonNull ViewGroup collection, int position) {
|
||||
AlbumCoverStyle albumCoverStyle = AlbumCoverStyle.values()[position];
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.preference_now_playing_screen_item, collection, false);
|
||||
collection.addView(layout);
|
||||
|
||||
ImageView image = layout.findViewById(R.id.image);
|
||||
TextView title = layout.findViewById(R.id.title);
|
||||
Glide.with(context).load(albumCoverStyle.drawableResId).into(image);
|
||||
title.setText(albumCoverStyle.titleRes);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(@NonNull ViewGroup collection,
|
||||
int position,
|
||||
@NonNull Object view) {
|
||||
collection.removeView((View) view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return AlbumCoverStyle.values().length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
|
||||
return view == object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return context.getString(AlbumCoverStyle.values()[position].titleRes);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,116 @@
|
|||
package code.name.monkey.retromusic.preferences
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.ui.fragments.AlbumCoverStyle
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.ViewUtil
|
||||
import com.afollestad.materialdialogs.DialogAction
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.bumptech.glide.Glide
|
||||
|
||||
|
||||
class AlbumCoverStylePreferenceDialog : DialogFragment(), ViewPager.OnPageChangeListener, MaterialDialog.SingleButtonCallback {
|
||||
|
||||
private var whichButtonClicked: DialogAction? = null
|
||||
private var viewPagerPosition: Int = 0
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
@SuppressLint("InflateParams") val view = LayoutInflater.from(activity).inflate(R.layout.preference_dialog_now_playing_screen, null)
|
||||
val viewPager = view.findViewById<ViewPager>(R.id.now_playing_screen_view_pager)
|
||||
viewPager.adapter = AlbumCoverStyleAdapter(activity!!)
|
||||
viewPager.addOnPageChangeListener(this)
|
||||
viewPager.pageMargin = ViewUtil.convertDpToPixel(32f, resources).toInt()
|
||||
viewPager.currentItem = PreferenceUtil.getInstance().albumCoverStyle.ordinal
|
||||
|
||||
return MaterialDialog.Builder(activity!!)
|
||||
.title(R.string.pref_title_album_cover_style)
|
||||
.positiveText(android.R.string.ok)
|
||||
.negativeText(android.R.string.cancel)
|
||||
.onAny(this)
|
||||
.customView(view, false)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun onClick(dialog: MaterialDialog,
|
||||
which: DialogAction) {
|
||||
whichButtonClicked = which
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface?) {
|
||||
super.onDismiss(dialog)
|
||||
if (whichButtonClicked == DialogAction.POSITIVE) {
|
||||
val nowPlayingScreen = AlbumCoverStyle.values()[viewPagerPosition]
|
||||
PreferenceUtil.getInstance().albumCoverStyle = nowPlayingScreen
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
this.viewPagerPosition = position
|
||||
}
|
||||
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
|
||||
}
|
||||
|
||||
private class AlbumCoverStyleAdapter internal constructor(private val context: Context) : PagerAdapter() {
|
||||
|
||||
override fun instantiateItem(collection: ViewGroup, position: Int): Any {
|
||||
val albumCoverStyle = AlbumCoverStyle.values()[position]
|
||||
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val layout = inflater.inflate(R.layout.preference_now_playing_screen_item, collection, false) as ViewGroup
|
||||
collection.addView(layout)
|
||||
|
||||
val image = layout.findViewById<ImageView>(R.id.image)
|
||||
val title = layout.findViewById<TextView>(R.id.title)
|
||||
Glide.with(context).load(albumCoverStyle.drawableResId).into(image)
|
||||
title.setText(albumCoverStyle.titleRes)
|
||||
|
||||
return layout
|
||||
}
|
||||
|
||||
override fun destroyItem(collection: ViewGroup,
|
||||
position: Int,
|
||||
view: Any) {
|
||||
collection.removeView(view as View)
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return AlbumCoverStyle.values().size
|
||||
}
|
||||
|
||||
override fun isViewFromObject(view: View, `object`: Any): Boolean {
|
||||
return view === `object`
|
||||
}
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence? {
|
||||
return context.getString(AlbumCoverStyle.values()[position].titleRes)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG: String = AlbumCoverStylePreferenceDialog::class.java.simpleName
|
||||
|
||||
fun newInstance(): AlbumCoverStylePreferenceDialog {
|
||||
return AlbumCoverStylePreferenceDialog()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package code.name.monkey.retromusic.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference;
|
||||
|
||||
|
||||
public class BlacklistPreference extends ATEDialogPreference {
|
||||
public BlacklistPreference(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public BlacklistPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public BlacklistPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public BlacklistPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package code.name.monkey.retromusic.preferences
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference
|
||||
|
||||
|
||||
class BlacklistPreference : ATEDialogPreference {
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
package code.name.monkey.retromusic.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference;
|
||||
|
||||
|
||||
public class NowPlayingScreenPreference extends ATEDialogPreference {
|
||||
public NowPlayingScreenPreference(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public NowPlayingScreenPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public NowPlayingScreenPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public NowPlayingScreenPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package code.name.monkey.retromusic.preferences
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
|
||||
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference
|
||||
|
||||
|
||||
class NowPlayingScreenPreference : ATEDialogPreference {
|
||||
constructor(context: Context) : super(context) {}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {}
|
||||
}
|
|
@ -1,166 +0,0 @@
|
|||
package code.name.monkey.retromusic.preferences;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.bumptech.glide.Glide;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.viewpager.widget.PagerAdapter;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.App;
|
||||
import code.name.monkey.retromusic.ui.fragments.NowPlayingScreen;
|
||||
import code.name.monkey.retromusic.util.NavigationUtil;
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil;
|
||||
import code.name.monkey.retromusic.util.ViewUtil;
|
||||
|
||||
|
||||
public class NowPlayingScreenPreferenceDialog extends DialogFragment implements
|
||||
ViewPager.OnPageChangeListener, MaterialDialog.SingleButtonCallback {
|
||||
public static final String TAG = NowPlayingScreenPreferenceDialog.class.getSimpleName();
|
||||
|
||||
private DialogAction whichButtonClicked;
|
||||
private int viewPagerPosition;
|
||||
|
||||
public static NowPlayingScreenPreferenceDialog newInstance() {
|
||||
return new NowPlayingScreenPreferenceDialog();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
@SuppressLint("InflateParams") View view = LayoutInflater.from(getActivity())
|
||||
.inflate(R.layout.preference_dialog_now_playing_screen, null);
|
||||
ViewPager viewPager = view.findViewById(R.id.now_playing_screen_view_pager);
|
||||
viewPager.setAdapter(new NowPlayingScreenAdapter(getActivity()));
|
||||
viewPager.addOnPageChangeListener(this);
|
||||
viewPager.setPageMargin((int) ViewUtil.convertDpToPixel(32, getResources()));
|
||||
viewPager.setCurrentItem(PreferenceUtil.getInstance().getNowPlayingScreen().ordinal());
|
||||
|
||||
return new MaterialDialog.Builder(getActivity())
|
||||
.title(R.string.pref_title_now_playing_screen_appearance)
|
||||
.positiveText(android.R.string.ok)
|
||||
.negativeText(android.R.string.cancel)
|
||||
.onAny(this)
|
||||
.customView(view, false)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog,
|
||||
@NonNull DialogAction which) {
|
||||
whichButtonClicked = which;
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
super.onDismiss(dialog);
|
||||
if (whichButtonClicked == DialogAction.POSITIVE) {
|
||||
NowPlayingScreen nowPlayingScreen = NowPlayingScreen.values()[viewPagerPosition];
|
||||
if (isNowPlayingThemes(nowPlayingScreen)) {
|
||||
String result = getString(nowPlayingScreen.titleRes) + " theme is Pro version feature.";
|
||||
Toast.makeText(getContext(), result, Toast.LENGTH_SHORT).show();
|
||||
NavigationUtil.goToProVersion(getActivity());
|
||||
} else {
|
||||
PreferenceUtil.getInstance().setNowPlayingScreen(nowPlayingScreen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNowPlayingThemes(NowPlayingScreen nowPlayingScreen) {
|
||||
|
||||
/*if (nowPlayingScreen.equals(NowPlayingScreen.BLUR_CARD)) {
|
||||
PreferenceUtil.getInstance().resetCarouselEffect();
|
||||
PreferenceUtil.getInstance().resetCircularAlbumArt();
|
||||
}*/
|
||||
|
||||
/* return (nowPlayingScreen.equals(NowPlayingScreen.FULL) ||
|
||||
nowPlayingScreen.equals(NowPlayingScreen.CARD) ||
|
||||
nowPlayingScreen.equals(NowPlayingScreen.PLAIN) ||
|
||||
nowPlayingScreen.equals(NowPlayingScreen.BLUR) ||
|
||||
nowPlayingScreen.equals(NowPlayingScreen.COLOR) ||
|
||||
nowPlayingScreen.equals(NowPlayingScreen.SIMPLE) ||
|
||||
nowPlayingScreen.equals(NowPlayingScreen.TINY) ||
|
||||
nowPlayingScreen.equals(NowPlayingScreen.BLUR_CARD)||
|
||||
nowPlayingScreen.equals(NowPlayingScreen.ADAPTIVE))
|
||||
&& !App.Companion.isProVersion();*/
|
||||
return !App.Companion.isProVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageSelected(int position) {
|
||||
this.viewPagerPosition = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageScrollStateChanged(int state) {
|
||||
|
||||
}
|
||||
|
||||
private static class NowPlayingScreenAdapter extends PagerAdapter {
|
||||
|
||||
private Context context;
|
||||
|
||||
NowPlayingScreenAdapter(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Object instantiateItem(@NonNull ViewGroup collection, int position) {
|
||||
NowPlayingScreen nowPlayingScreen = NowPlayingScreen.values()[position];
|
||||
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.preference_now_playing_screen_item, collection, false);
|
||||
collection.addView(layout);
|
||||
|
||||
ImageView image = layout.findViewById(R.id.image);
|
||||
TextView title = layout.findViewById(R.id.title);
|
||||
Glide.with(context).load(nowPlayingScreen.drawableResId).into(image);
|
||||
title.setText(nowPlayingScreen.titleRes);
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyItem(@NonNull ViewGroup collection,
|
||||
int position,
|
||||
@NonNull Object view) {
|
||||
collection.removeView((View) view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
return NowPlayingScreen.values().length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
|
||||
return view == object;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getPageTitle(int position) {
|
||||
return context.getString(NowPlayingScreen.values()[position].titleRes);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
package code.name.monkey.retromusic.preferences
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.viewpager.widget.PagerAdapter
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.ui.fragments.NowPlayingScreen
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.ViewUtil
|
||||
import com.afollestad.materialdialogs.DialogAction
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.bumptech.glide.Glide
|
||||
|
||||
|
||||
class NowPlayingScreenPreferenceDialog : DialogFragment(), ViewPager.OnPageChangeListener, MaterialDialog.SingleButtonCallback {
|
||||
|
||||
private var whichButtonClicked: DialogAction? = null
|
||||
private var viewPagerPosition: Int = 0
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
@SuppressLint("InflateParams") val view = LayoutInflater.from(activity)
|
||||
.inflate(R.layout.preference_dialog_now_playing_screen, null)
|
||||
val viewPager = view.findViewById<ViewPager>(R.id.now_playing_screen_view_pager)
|
||||
viewPager.adapter = NowPlayingScreenAdapter(activity!!)
|
||||
viewPager.addOnPageChangeListener(this)
|
||||
viewPager.pageMargin = ViewUtil.convertDpToPixel(32f, resources).toInt()
|
||||
viewPager.currentItem = PreferenceUtil.getInstance().nowPlayingScreen.ordinal
|
||||
|
||||
return MaterialDialog.Builder(activity!!)
|
||||
.title(R.string.pref_title_now_playing_screen_appearance)
|
||||
.positiveText(android.R.string.ok)
|
||||
.negativeText(android.R.string.cancel)
|
||||
.onAny(this)
|
||||
.customView(view, false)
|
||||
.build()
|
||||
}
|
||||
|
||||
override fun onClick(dialog: MaterialDialog,
|
||||
which: DialogAction) {
|
||||
whichButtonClicked = which
|
||||
}
|
||||
|
||||
override fun onDismiss(dialog: DialogInterface?) {
|
||||
super.onDismiss(dialog)
|
||||
if (whichButtonClicked == DialogAction.POSITIVE) {
|
||||
val nowPlayingScreen = NowPlayingScreen.values()[viewPagerPosition]
|
||||
if (isNowPlayingThemes(nowPlayingScreen)) {
|
||||
val result = getString(nowPlayingScreen.titleRes) + " theme is Pro version feature."
|
||||
Toast.makeText(context, result, Toast.LENGTH_SHORT).show()
|
||||
NavigationUtil.goToProVersion(activity!!)
|
||||
} else {
|
||||
PreferenceUtil.getInstance().nowPlayingScreen = nowPlayingScreen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun isNowPlayingThemes(nowPlayingScreen: NowPlayingScreen): Boolean {
|
||||
|
||||
if (nowPlayingScreen == NowPlayingScreen.BLUR_CARD) {
|
||||
PreferenceUtil.getInstance().resetCarouselEffect()
|
||||
PreferenceUtil.getInstance().resetCircularAlbumArt()
|
||||
}
|
||||
|
||||
return (nowPlayingScreen == NowPlayingScreen.FULL ||
|
||||
nowPlayingScreen == NowPlayingScreen.CARD ||
|
||||
nowPlayingScreen == NowPlayingScreen.PLAIN ||
|
||||
nowPlayingScreen == NowPlayingScreen.BLUR ||
|
||||
nowPlayingScreen == NowPlayingScreen.COLOR ||
|
||||
nowPlayingScreen == NowPlayingScreen.SIMPLE ||
|
||||
nowPlayingScreen == NowPlayingScreen.BLUR_CARD ||
|
||||
nowPlayingScreen == NowPlayingScreen.ADAPTIVE)
|
||||
&& !App.isProVersion
|
||||
|
||||
}
|
||||
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
this.viewPagerPosition = position
|
||||
}
|
||||
|
||||
override fun onPageScrollStateChanged(state: Int) {
|
||||
|
||||
}
|
||||
|
||||
private class NowPlayingScreenAdapter internal constructor(private val context: Context) : PagerAdapter() {
|
||||
|
||||
override fun instantiateItem(collection: ViewGroup, position: Int): Any {
|
||||
val nowPlayingScreen = NowPlayingScreen.values()[position]
|
||||
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val layout = inflater.inflate(R.layout.preference_now_playing_screen_item, collection, false) as ViewGroup
|
||||
collection.addView(layout)
|
||||
|
||||
val image = layout.findViewById<ImageView>(R.id.image)
|
||||
val title = layout.findViewById<TextView>(R.id.title)
|
||||
Glide.with(context).load(nowPlayingScreen.drawableResId).into(image)
|
||||
title.setText(nowPlayingScreen.titleRes)
|
||||
|
||||
return layout
|
||||
}
|
||||
|
||||
override fun destroyItem(collection: ViewGroup,
|
||||
position: Int,
|
||||
view: Any) {
|
||||
collection.removeView(view as View)
|
||||
}
|
||||
|
||||
override fun getCount(): Int {
|
||||
return NowPlayingScreen.values().size
|
||||
}
|
||||
|
||||
override fun isViewFromObject(view: View, `object`: Any): Boolean {
|
||||
return view === `object`
|
||||
}
|
||||
|
||||
override fun getPageTitle(position: Int): CharSequence? {
|
||||
return context.getString(NowPlayingScreen.values()[position].titleRes)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TAG: String = NowPlayingScreenPreferenceDialog::class.java.simpleName
|
||||
|
||||
fun newInstance(): NowPlayingScreenPreferenceDialog {
|
||||
return NowPlayingScreenPreferenceDialog()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package code.name.monkey.retromusic.providers.interfaces;
|
||||
|
||||
import code.name.monkey.retromusic.model.Album;
|
||||
import code.name.monkey.retromusic.model.Artist;
|
||||
import code.name.monkey.retromusic.model.Genre;
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist;
|
||||
import io.reactivex.Observable;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by hemanths on 11/08/17.
|
||||
*/
|
||||
|
||||
public interface Repository {
|
||||
|
||||
Observable<ArrayList<Song>> getAllSongs();
|
||||
|
||||
Observable<ArrayList<Song>> getSuggestionSongs();
|
||||
|
||||
Observable<Song> getSong(int id);
|
||||
|
||||
Observable<ArrayList<Album>> getAllAlbums();
|
||||
|
||||
Observable<ArrayList<Album>> getRecentAlbums();
|
||||
|
||||
Observable<ArrayList<Album>> getTopAlbums();
|
||||
|
||||
Observable<Album> getAlbum(int albumId);
|
||||
|
||||
Observable<ArrayList<Artist>> getAllArtists();
|
||||
|
||||
Observable<ArrayList<Artist>> getRecentArtists();
|
||||
|
||||
Observable<ArrayList<Artist>> getTopArtists();
|
||||
|
||||
|
||||
Observable<Artist> getArtistById(long artistId);
|
||||
|
||||
Observable<ArrayList<Playlist>> getAllPlaylists();
|
||||
|
||||
Observable<ArrayList<Song>> getFavoriteSongs();
|
||||
|
||||
Observable<ArrayList<Object>> search(String query);
|
||||
|
||||
Observable<ArrayList<Song>> getPlaylistSongs(Playlist playlist);
|
||||
|
||||
Observable<ArrayList<Playlist>> getHomeList();
|
||||
|
||||
Observable<ArrayList<AbsSmartPlaylist>> getAllThings();
|
||||
|
||||
Observable<ArrayList<Genre>> getAllGenres();
|
||||
|
||||
Observable<ArrayList<Song>> getGenre(int genreId);
|
||||
|
||||
Observable<File> downloadLrcFile(final String title, final String artist, final long duration);
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue