diff --git a/app/app.iml b/app/app.iml
index 2566dab7..e41380a5 100644
--- a/app/app.iml
+++ b/app/app.iml
@@ -8,16 +8,16 @@
-
-
-
+
+
+
- generateNormalDebugSources
+ generateSansDebugSources
-
+
@@ -25,87 +25,90 @@
-
-
+
+
-
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -148,13 +151,16 @@
+
+
+
-
+
@@ -166,7 +172,6 @@
-
@@ -189,87 +194,86 @@
-
+
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
-
+
+
-
-
-
+
+
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
-
+
+
-
-
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 32115020..9b55926c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -142,7 +142,6 @@ dependencies {
implementation 'com.anjlab.android.iab.v3:library:1.0.44'
/*UI Library*/
- implementation 'uk.co.chrisjenx:calligraphy:2.3.0'
implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2'
implementation 'com.r0adkll:slidableactivity:2.0.6'
/*Backend all*/
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index ca258b34..f9c70b14 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -14,7 +14,7 @@
+ android:windowSoftInputMode="stateVisible"/>
diff --git a/app/src/main/assets/retro-changelog.html b/app/src/main/assets/retro-changelog.html
index 281b5626..9f5329b3 100644
--- a/app/src/main/assets/retro-changelog.html
+++ b/app/src/main/assets/retro-changelog.html
@@ -1 +1 @@
-
Version 2.2.100
- Click new music mix to play songs
- Gradient image option for gird list
- Clear button for playing queue
- Click toolbar (Library) to open options
- Folder list back button
- New theme Fit
- On library click on toolbar for accessing main menu
- On home click on toolbar for accessing search
- BottomSheetDialogue is now adaptable to screens, background colour and text size
consistency.
- Removed coloured navigation bar option to making app adapt the primary colour
- Swipe up gesture for now playing removed, replaced with "tap to open", To achieve
transparent navigation bar for desired themes.
- Improved tablet UI and home screen by adding suggestions toggle banner issues.
- Improving lyrics page
FAQ's
*If you face any UI related issues you clear app data and cache, if its
not working try to
uninstall and install again.
\ No newline at end of file
+
Version 2.2.100
- Click new music mix to play songs
- Gradient image option for gird list
- Clear button for playing queue
- Click toolbar (Library) to open options
- Folder list back button
- New theme Fit
- On library click on toolbar for accessing main menu
- On home click on toolbar for accessing search
- BottomSheetDialogue is now adaptable to screens, background colour and text size
consistency.
- Removed coloured navigation bar option to making app adapt the primary colour
- Swipe up gesture for now playing removed, replaced with "tap to open", To achieve
transparent navigation bar for desired themes.
- Improved tablet UI and home screen by adding suggestions toggle banner issues.
- Improving lyrics page
FAQ's
*If you face any UI related issues you clear app data and cache, if its
not working try to
uninstall and install again.
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/RetroApplication.kt b/app/src/main/java/code/name/monkey/retromusic/App.kt
similarity index 94%
rename from app/src/main/java/code/name/monkey/retromusic/RetroApplication.kt
rename to app/src/main/java/code/name/monkey/retromusic/App.kt
index 176e6a03..0c3d590d 100644
--- a/app/src/main/java/code/name/monkey/retromusic/RetroApplication.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/App.kt
@@ -6,9 +6,8 @@ import code.name.monkey.appthemehelper.ThemeStore
import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.TransactionDetails
import com.bumptech.glide.Glide
-import uk.co.chrisjenx.calligraphy.CalligraphyConfig
-class RetroApplication : MultiDexApplication() {
+class App : MultiDexApplication() {
lateinit var billingProcessor: BillingProcessor
@@ -67,7 +66,7 @@ class RetroApplication : MultiDexApplication() {
const val PRO_VERSION_PRODUCT_ID = "pro_version"
- lateinit var instance: RetroApplication
+ lateinit var instance: App
private set
val context: Context
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.java
deleted file mode 100644
index 2a8cfa7c..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package code.name.monkey.retromusic.dialogs;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import java.util.ArrayList;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.DefaultItemAnimator;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-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.loaders.PlaylistLoader;
-import code.name.monkey.retromusic.model.Playlist;
-import code.name.monkey.retromusic.model.Song;
-import code.name.monkey.retromusic.ui.adapter.playlist.AddToPlaylist;
-import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
-
-/**
- * @author Karim Abou Zeid (kabouzeid), Aidan Follestad (afollestad)
- */
-public class AddToPlaylistDialog extends RoundedBottomSheetDialogFragment {
-
- @BindView(R.id.playlists)
- RecyclerView playlist;
-
- @BindView(R.id.title)
- TextView title;
-
- @NonNull
- public static AddToPlaylistDialog create(Song song) {
- ArrayList list = new ArrayList<>();
- list.add(song);
- return create(list);
- }
-
- @NonNull
- public static AddToPlaylistDialog create(ArrayList songs) {
- AddToPlaylistDialog dialog = new AddToPlaylistDialog();
- Bundle args = new Bundle();
- args.putParcelableArrayList("songs", songs);
- 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_add_to_playlist, container, false);
- ButterKnife.bind(this, layout);
- return layout;
- }
-
- @SuppressWarnings("ConstantConditions")
- @OnClick(R.id.action_add_playlist)
- void newPlaylist() {
- final ArrayList songs = getArguments().getParcelableArrayList("songs");
- CreatePlaylistDialog.create(songs)
- .show(getActivity().getSupportFragmentManager(), "ADD_TO_PLAYLIST");
- dismiss();
- }
-
- @SuppressWarnings("ConstantConditions")
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- title.setTextColor(ThemeStore.textColorPrimary(getContext()));
- final ArrayList songs = getArguments().getParcelableArrayList("songs");
- final ArrayList playlists = PlaylistLoader.INSTANCE.getAllPlaylists(getActivity()).blockingFirst();
- final AddToPlaylist playlistAdapter = new AddToPlaylist(getActivity(), playlists, R.layout.item_playlist, songs, getDialog());
- playlist.setLayoutManager(new LinearLayoutManager(getContext()));
- playlist.setItemAnimator(new DefaultItemAnimator());
- playlist.setAdapter(playlistAdapter);
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt
new file mode 100644
index 00000000..b8b68391
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt
@@ -0,0 +1,68 @@
+package code.name.monkey.retromusic.dialogs
+
+import android.os.Bundle
+import android.view.LayoutInflater
+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
+import code.name.monkey.retromusic.model.Song
+import code.name.monkey.retromusic.ui.adapter.playlist.AddToPlaylist
+import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
+import kotlinx.android.synthetic.main.dialog_add_to_playlist.*
+import java.util.*
+
+/**
+ * @author Karim Abou Zeid (kabouzeid), Aidan Follestad (afollestad)
+ */
+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
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ actionAddPlaylist.setOnClickListener {
+ val songs = arguments!!.getParcelableArrayList("songs")
+ CreatePlaylistDialog.create(songs).show(activity!!.supportFragmentManager, "ADD_TO_PLAYLIST")
+ dismiss()
+ }
+
+ bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!))
+ val songs = arguments!!.getParcelableArrayList("songs")
+ val playlists = PlaylistLoader.getAllPlaylists(activity!!).blockingFirst()
+ val playlistAdapter = AddToPlaylist(activity!!, playlists, R.layout.item_playlist, songs!!, dialog)
+ recyclerView.apply {
+ layoutManager = LinearLayoutManager(context)
+ itemAnimator = DefaultItemAnimator()
+ adapter = playlistAdapter
+ }
+ }
+
+ companion object {
+
+ fun create(song: Song): AddToPlaylistDialog {
+ val list = ArrayList()
+ list.add(song)
+ return create(list)
+ }
+
+ fun create(songs: ArrayList): AddToPlaylistDialog {
+ val dialog = AddToPlaylistDialog()
+ val args = Bundle()
+ args.putParcelableArrayList("songs", songs)
+ dialog.arguments = args
+ return dialog
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/ClearSmartPlaylistDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/ClearSmartPlaylistDialog.java
deleted file mode 100644
index 735b0f9d..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/ClearSmartPlaylistDialog.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package code.name.monkey.retromusic.dialogs;
-
-import android.app.Dialog;
-import android.os.Bundle;
-import android.text.Html;
-
-import com.afollestad.materialdialogs.DialogAction;
-import com.afollestad.materialdialogs.MaterialDialog;
-
-import androidx.annotation.NonNull;
-import androidx.fragment.app.DialogFragment;
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist;
-
-
-public class ClearSmartPlaylistDialog extends DialogFragment {
-
- @NonNull
- public static ClearSmartPlaylistDialog create(AbsSmartPlaylist playlist) {
- ClearSmartPlaylistDialog dialog = new ClearSmartPlaylistDialog();
- Bundle args = new Bundle();
- args.putParcelable("playlist", playlist);
- dialog.setArguments(args);
- return dialog;
- }
-
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- //noinspection unchecked
- final AbsSmartPlaylist playlist = getArguments().getParcelable("playlist");
- int title = R.string.clear_playlist_title;
- //noinspection ConstantConditions
- CharSequence content = Html.fromHtml(getString(R.string.clear_playlist_x, playlist.name));
-
- return new MaterialDialog.Builder(getActivity())
- .title(title)
- .content(content)
- .positiveText(R.string.clear_action)
- .negativeText(android.R.string.cancel)
- .onPositive(new MaterialDialog.SingleButtonCallback() {
- @Override
- public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
- if (getActivity() == null) {
- return;
- }
- playlist.clear(getActivity());
- }
- })
- .build();
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/ClearSmartPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/ClearSmartPlaylistDialog.kt
new file mode 100644
index 00000000..500d95dc
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/ClearSmartPlaylistDialog.kt
@@ -0,0 +1,45 @@
+package code.name.monkey.retromusic.dialogs
+
+import android.app.Dialog
+import android.os.Bundle
+import android.text.Html
+import androidx.fragment.app.DialogFragment
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist
+import com.afollestad.materialdialogs.MaterialDialog
+
+
+class ClearSmartPlaylistDialog : DialogFragment() {
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+
+ val playlist = arguments!!.getParcelable("playlist")
+ val title = R.string.clear_playlist_title
+
+ val content = Html.fromHtml(getString(R.string.clear_playlist_x, playlist!!.name))
+
+ return MaterialDialog.Builder(activity!!)
+ .title(title)
+ .content(content)
+ .positiveText(R.string.clear_action)
+ .negativeText(android.R.string.cancel)
+ .onPositive { _, _ ->
+ if (activity == null) {
+ return@onPositive
+ }
+ playlist.clear(activity)
+ }
+ .build()
+ }
+
+ companion object {
+
+ fun create(playlist: AbsSmartPlaylist): ClearSmartPlaylistDialog {
+ val dialog = ClearSmartPlaylistDialog()
+ val args = Bundle()
+ args.putParcelable("playlist", playlist)
+ dialog.arguments = args
+ return dialog
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.java
deleted file mode 100644
index b1b7cf45..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.java
+++ /dev/null
@@ -1,123 +0,0 @@
-package code.name.monkey.retromusic.dialogs;
-
-import android.content.res.ColorStateList;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.google.android.material.button.MaterialButton;
-import com.google.android.material.textfield.TextInputEditText;
-import com.google.android.material.textfield.TextInputLayout;
-
-import java.util.ArrayList;
-import java.util.Objects;
-
-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.PlaylistsUtil;
-import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
-
-/**
- * @author Karim Abou Zeid (kabouzeid), Aidan Follestad (afollestad)
- */
-public class CreatePlaylistDialog extends RoundedBottomSheetDialogFragment {
-
- @BindView(R.id.option_1)
- TextInputEditText playlistName;
-
- @BindView(R.id.action_new_playlist)
- TextInputLayout textInputLayout;
-
- @BindView(R.id.action_cancel)
- MaterialButton actionCancel;
-
- @BindView(R.id.action_create)
- MaterialButton actionCreate;
-
- @BindView(R.id.title)
- TextView title;
-
- @NonNull
- public static CreatePlaylistDialog create() {
- return create((Song) null);
- }
-
- @NonNull
- public static CreatePlaylistDialog create(@Nullable Song song) {
- ArrayList list = new ArrayList<>();
- if (song != null) {
- list.add(song);
- }
- return create(list);
- }
-
- @NonNull
- public static CreatePlaylistDialog create(ArrayList songs) {
- CreatePlaylistDialog dialog = new CreatePlaylistDialog();
- Bundle args = new Bundle();
- args.putParcelableArrayList("songs", songs);
- 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_create_playlist, container, false);
- ButterKnife.bind(this, layout);
- return layout;
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- int accentColor = ThemeStore.accentColor(Objects.requireNonNull(getContext()));
-
- MaterialUtil.setTint(actionCreate, true);
-
- MaterialUtil.setTint(actionCancel, false);
-
- MaterialUtil.setTint(textInputLayout, true);
-
-
- playlistName.setHintTextColor(ColorStateList.valueOf(accentColor));
- playlistName.setTextColor(ThemeStore.textColorPrimary(getContext()));
-
- title.setTextColor(ThemeStore.textColorPrimary(getContext()));
- }
-
- @OnClick({R.id.action_cancel, R.id.action_create})
- void actions(View view) {
- switch (view.getId()) {
- case R.id.action_cancel:
- dismiss();
- break;
- case R.id.action_create:
- if (getActivity() == null) {
- return;
- }
- if (!playlistName.getText().toString().trim().isEmpty()) {
- final int playlistId = PlaylistsUtil
- .createPlaylist(getActivity(), playlistName.getText().toString());
- if (playlistId != -1 && getActivity() != null) {
- //noinspection unchecked
- ArrayList songs = getArguments().getParcelableArrayList("songs");
- if (songs != null) {
- PlaylistsUtil.addToPlaylist(getActivity(), songs, playlistId, true);
- }
- }
- }
- break;
- }
- dismiss();
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt
new file mode 100644
index 00000000..f2245eba
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt
@@ -0,0 +1,83 @@
+package code.name.monkey.retromusic.dialogs
+
+import android.content.Context
+import android.content.res.ColorStateList
+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
+import code.name.monkey.retromusic.model.Song
+import code.name.monkey.retromusic.util.PlaylistsUtil
+import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
+import kotlinx.android.synthetic.main.dialog_playlist.*
+import java.util.*
+
+/**
+ * @author Karim Abou Zeid (kabouzeid), Aidan Follestad (afollestad)
+ */
+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
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val accentColor = ThemeStore.accentColor(Objects.requireNonNull(context))
+
+ MaterialUtil.setTint(actionCreate, true)
+ MaterialUtil.setTint(actionCancel, false)
+ MaterialUtil.setTint(actionNewPlaylistContainer, true)
+
+ actionNewPlaylist.setHintTextColor(ColorStateList.valueOf(accentColor))
+ actionNewPlaylist.setTextColor(ThemeStore.textColorPrimary(context!!))
+ bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!))
+
+
+ actionCancel.setOnClickListener { dismiss() }
+ actionCreate.setOnClickListener {
+ if (activity == null) {
+ return@setOnClickListener
+ }
+ if (!actionNewPlaylist!!.text!!.toString().trim { it <= ' ' }.isEmpty()) {
+ val playlistId = PlaylistsUtil
+ .createPlaylist(activity!!, actionNewPlaylist!!.text!!.toString())
+ if (playlistId != -1 && activity != null) {
+
+ val songs = arguments!!.getParcelableArrayList("songs")
+ if (songs != null) {
+ PlaylistsUtil.addToPlaylist(activity!!, songs, playlistId, true)
+ }
+ }
+ }
+ dismiss()
+ }
+ }
+
+ companion object {
+
+ @JvmOverloads
+ fun create(song: Song? = null): CreatePlaylistDialog {
+ val list = ArrayList()
+ if (song != null) {
+ list.add(song)
+ }
+ return create(list)
+ }
+
+ fun create(songs: ArrayList): CreatePlaylistDialog {
+ val dialog = CreatePlaylistDialog()
+ val args = Bundle()
+ args.putParcelableArrayList("songs", songs)
+ dialog.arguments = args
+ return dialog
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.java
deleted file mode 100644
index a7681518..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.java
+++ /dev/null
@@ -1,102 +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.Playlist;
-import code.name.monkey.retromusic.util.PlaylistsUtil;
-import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
-
-
-public class DeletePlaylistDialog 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 DeletePlaylistDialog create(Playlist playlist) {
- ArrayList list = new ArrayList<>();
- list.add(playlist);
- return create(list);
- }
-
- @NonNull
- public static DeletePlaylistDialog create(ArrayList playlists) {
- DeletePlaylistDialog dialog = new DeletePlaylistDialog();
- Bundle args = new Bundle();
- args.putParcelableArrayList("playlists", playlists);
- 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_delete, container, false);
- ButterKnife.bind(this, layout);
- return layout;
- }
-
- @SuppressWarnings("ConstantConditions")
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- //noinspection unchecked
- final ArrayList playlists = getArguments().getParcelableArrayList("playlists");
- int title;
- CharSequence content;
- //noinspection ConstantConditions
- if (playlists.size() > 1) {
- content = Html.fromHtml(getString(R.string.delete_x_playlists, playlists.size()));
- } else {
- content = Html.fromHtml(getString(R.string.delete_playlist_x, playlists.get(0).name));
- }
- this.title.setText(content);
- this.title.setTextColor(ThemeStore.textColorPrimary(getContext()));
-
- actionDelete.setText(R.string.action_delete);
-
- MaterialUtil.setTint(actionDelete, true);
- MaterialUtil.setTint(actionCancel, false);
-
-
- }
-
- @OnClick({R.id.action_cancel, R.id.action_delete})
- void actions(View view) {
- final ArrayList playlists = getArguments().getParcelableArrayList("playlists");
- switch (view.getId()) {
- case R.id.action_delete:
- if (getActivity() == null)
- return;
- PlaylistsUtil.deletePlaylists(getActivity(), playlists);
- break;
- default:
- }
- dismiss();
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.kt
new file mode 100644
index 00000000..78a2969b
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.kt
@@ -0,0 +1,70 @@
+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 butterknife.ButterKnife
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.model.Playlist
+import code.name.monkey.retromusic.util.PlaylistsUtil
+import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
+import kotlinx.android.synthetic.main.dialog_remove_from_playlist.*
+import java.util.*
+
+
+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
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+
+ val playlists = arguments!!.getParcelableArrayList("playlists")
+ val content: CharSequence
+
+ content = if (playlists!!.size > 1) {
+ Html.fromHtml(getString(R.string.delete_x_playlists, playlists.size))
+ } else {
+ Html.fromHtml(getString(R.string.delete_playlist_x, playlists[0].name))
+ }
+ bannerTitle.text = content
+ bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!))
+
+ actionRemove.setText(R.string.action_delete)
+ actionRemove.setTextColor(ThemeStore.textColorSecondary(context!!))
+ actionCancel.setTextColor(ThemeStore.textColorSecondary(context!!))
+
+ actionCancel.setOnClickListener { dismiss() }
+ actionRemove.setOnClickListener {
+ PlaylistsUtil.deletePlaylists(activity!!, playlists)
+ dismiss()
+ }
+ }
+
+
+ companion object {
+
+ fun create(playlist: Playlist): DeletePlaylistDialog {
+ val list = ArrayList()
+ list.add(playlist)
+ return create(list)
+ }
+
+ fun create(playlist: ArrayList): DeletePlaylistDialog {
+ val dialog = DeletePlaylistDialog()
+ val args = Bundle()
+ args.putParcelableArrayList("playlist", playlist)
+ dialog.arguments = args
+ return dialog
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/MainOptionsBottomSheetDialogFragment.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/MainOptionsBottomSheetDialogFragment.java
deleted file mode 100644
index 0374f023..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/MainOptionsBottomSheetDialogFragment.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package code.name.monkey.retromusic.dialogs;
-
-import android.content.res.ColorStateList;
-import android.graphics.Bitmap;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.google.android.material.button.MaterialButton;
-
-import java.io.File;
-import java.util.Calendar;
-import java.util.List;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.AppCompatTextView;
-import androidx.core.content.ContextCompat;
-import butterknife.BindView;
-import butterknife.BindViews;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import code.name.monkey.appthemehelper.ThemeStore;
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.RetroApplication;
-import code.name.monkey.retromusic.ui.activities.MainActivity;
-import code.name.monkey.retromusic.ui.fragments.mainactivity.folders.FoldersFragment;
-import code.name.monkey.retromusic.util.Compressor;
-import code.name.monkey.retromusic.util.NavigationUtil;
-import code.name.monkey.retromusic.util.PreferenceUtil;
-import code.name.monkey.retromusic.views.CircularImageView;
-import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.CompositeDisposable;
-import io.reactivex.schedulers.Schedulers;
-
-import static code.name.monkey.retromusic.Constants.USER_PROFILE;
-
-public class MainOptionsBottomSheetDialogFragment extends RoundedBottomSheetDialogFragment {
-
- private static final String TAG = "MainOptionsBottomSheetD";
- private static ButterKnife.Setter textColor = (view, value, index) -> view.setTextColor(ColorStateList.valueOf(value));
-
-
- @BindViews({R.id.action_folders, R.id.action_about, R.id.action_buy_pro, R.id.action_rate,
- R.id.action_sleep_timer})
- List materialButtons;
-
- @BindView(R.id.user_image_bottom)
- CircularImageView userImageBottom;
-
- @BindView(R.id.title_welcome)
- AppCompatTextView titleWelcome;
-
- @BindView(R.id.text)
- AppCompatTextView text;
-
- private CompositeDisposable disposable = new CompositeDisposable();
-
- public static MainOptionsBottomSheetDialogFragment newInstance(int selected_id) {
- Bundle bundle = new Bundle();
- bundle.putInt("selected_id", selected_id);
- MainOptionsBottomSheetDialogFragment fragment = new MainOptionsBottomSheetDialogFragment();
- fragment.setArguments(bundle);
- return fragment;
- }
-
- public static MainOptionsBottomSheetDialogFragment newInstance() {
- return new MainOptionsBottomSheetDialogFragment();
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- disposable.clear();
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
- View layout = inflater.inflate(R.layout.fragment_main_options, container, false);
- ButterKnife.bind(this, layout);
- layout.findViewById(R.id.action_buy_pro).setVisibility(RetroApplication.Companion.isProVersion() ? View.GONE : View.VISIBLE);
- //ButterKnife.apply(materialButtons, textColor, ThemeStore.textColorPrimary(getContext()));
- return layout;
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- text.setTextColor(ThemeStore.textColorSecondary(getContext()));
- titleWelcome.setTextColor(ThemeStore.textColorPrimary(getContext()));
- titleWelcome.setText(String.format("%s %s!", getTimeOfTheDay(), PreferenceUtil.getInstance().getUserName()));
- loadImageFromStorage();
- }
-
- @OnClick({R.id.action_folders, R.id.user_info_container, R.id.action_settings, R.id.action_sleep_timer, R.id.action_rate,
- R.id.action_buy_pro, R.id.action_about})
- void onClick(View view) {
- MainActivity mainActivity = (MainActivity) getActivity();
- if (mainActivity == null) {
- return;
- }
- switch (view.getId()) {
- case R.id.action_folders:
- mainActivity.setCurrentFragment(FoldersFragment.newInstance(getContext()), true, FoldersFragment.TAG);
- break;
- case R.id.action_settings:
- NavigationUtil.goToSettings(mainActivity);
- break;
- case R.id.action_about:
- NavigationUtil.goToAbout(mainActivity);
- break;
- case R.id.action_buy_pro:
- NavigationUtil.goToProVersion(mainActivity);
- break;
- case R.id.action_sleep_timer:
- if (getFragmentManager() != null) {
- new SleepTimerDialog().show(getFragmentManager(), TAG);
- }
- break;
- case R.id.user_info_container:
- NavigationUtil.goToUserInfo(getActivity());
- break;
- case R.id.action_rate:
- NavigationUtil.goToPlayStore(mainActivity);
- break;
- }
- dismiss();
- }
-
- private String getTimeOfTheDay() {
- String message = getString(R.string.title_good_day);
- Calendar c = Calendar.getInstance();
- int timeOfDay = c.get(Calendar.HOUR_OF_DAY);
-
- if (timeOfDay >= 0 && timeOfDay < 6) {
- message = getString(R.string.title_good_night);
- } else if (timeOfDay >= 6 && timeOfDay < 12) {
- message = getString(R.string.title_good_morning);
- } else if (timeOfDay >= 12 && timeOfDay < 16) {
- message = getString(R.string.title_good_afternoon);
- } else if (timeOfDay >= 16 && timeOfDay < 20) {
- message = getString(R.string.title_good_evening);
- } else if (timeOfDay >= 20 && timeOfDay < 24) {
- message = getString(R.string.title_good_night);
- }
- return message;
- }
-
- private void loadImageFromStorage() {
- //noinspection ConstantConditions
- disposable.add(new Compressor(getContext())
- .setMaxHeight(300)
- .setMaxWidth(300)
- .setQuality(75)
- .setCompressFormat(Bitmap.CompressFormat.WEBP)
- .compressToBitmapAsFlowable(
- new File(PreferenceUtil.getInstance().getProfileImage(),USER_PROFILE))
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(userImageBottom::setImageBitmap,
- throwable -> userImageBottom.setImageDrawable(ContextCompat
- .getDrawable(getContext(), R.drawable.ic_person_flat))));
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/MainOptionsBottomSheetDialogFragment.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/MainOptionsBottomSheetDialogFragment.kt
new file mode 100644
index 00000000..50f76b85
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/MainOptionsBottomSheetDialogFragment.kt
@@ -0,0 +1,117 @@
+package code.name.monkey.retromusic.dialogs
+
+import android.graphics.Bitmap
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.core.content.ContextCompat
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.retromusic.Constants.USER_PROFILE
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.ui.activities.MainActivity
+import code.name.monkey.retromusic.util.Compressor
+import code.name.monkey.retromusic.util.NavigationUtil
+import code.name.monkey.retromusic.util.PreferenceUtil
+import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
+import io.reactivex.android.schedulers.AndroidSchedulers
+import io.reactivex.disposables.CompositeDisposable
+import io.reactivex.schedulers.Schedulers
+import kotlinx.android.synthetic.main.fragment_main_options.*
+import java.io.File
+import java.util.*
+
+class MainOptionsBottomSheetDialogFragment : RoundedBottomSheetDialogFragment(), View.OnClickListener {
+
+ private val disposable = CompositeDisposable()
+
+ private val timeOfTheDay: String
+ get() {
+ var message = getString(R.string.title_good_day)
+ val c = Calendar.getInstance()
+ val timeOfDay = c.get(Calendar.HOUR_OF_DAY)
+
+ when (timeOfDay) {
+ in 0..5 -> message = getString(R.string.title_good_night)
+ in 6..11 -> message = getString(R.string.title_good_morning)
+ in 12..15 -> message = getString(R.string.title_good_afternoon)
+ in 16..19 -> message = getString(R.string.title_good_evening)
+ in 20..23 -> message = getString(R.string.title_good_night)
+ }
+ return message
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ disposable.clear()
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
+ return inflater.inflate(R.layout.fragment_main_options, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ text!!.setTextColor(ThemeStore.textColorSecondary(context!!))
+ titleWelcome!!.setTextColor(ThemeStore.textColorPrimary(context!!))
+ titleWelcome!!.text = String.format("%s %s!", timeOfTheDay, PreferenceUtil.getInstance().userName)
+ loadImageFromStorage()
+
+ actionSettings.setOnClickListener(this)
+ actionAbout.setOnClickListener(this)
+ actionSleepTimer.setOnClickListener(this)
+ userInfoContainer.setOnClickListener(this)
+ actionRate.setOnClickListener(this)
+ }
+
+
+ override fun onClick(view: View) {
+ val mainActivity = activity as MainActivity? ?: return
+ when (view.id) {
+ R.id.actionSettings -> NavigationUtil.goToSettings(mainActivity)
+ R.id.actionAbout -> NavigationUtil.goToAbout(mainActivity)
+ R.id.actionSleepTimer -> if (fragmentManager != null) {
+ SleepTimerDialog().show(fragmentManager!!, TAG)
+ }
+ R.id.userInfoContainer -> NavigationUtil.goToUserInfo(activity!!)
+ R.id.actionRate -> NavigationUtil.goToPlayStore(mainActivity)
+ }
+ dismiss()
+ }
+
+ private fun loadImageFromStorage() {
+
+ disposable.add(Compressor(context!!)
+ .setMaxHeight(300)
+ .setMaxWidth(300)
+ .setQuality(75)
+ .setCompressFormat(Bitmap.CompressFormat.WEBP)
+ .compressToBitmapAsFlowable(
+ File(PreferenceUtil.getInstance().profileImage, USER_PROFILE))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe({ userImage!!.setImageBitmap(it) }, {
+ userImage!!.setImageDrawable(ContextCompat
+ .getDrawable(context!!, R.drawable.ic_person_flat))
+ }, {
+
+ }))
+ }
+
+ companion object {
+
+ private const val TAG: String = "MainOptionsBottomSheetD"
+
+ fun newInstance(selected_id: Int): MainOptionsBottomSheetDialogFragment {
+ val bundle = Bundle()
+ bundle.putInt("selected_id", selected_id)
+ val fragment = MainOptionsBottomSheetDialogFragment()
+ fragment.arguments = bundle
+ return fragment
+ }
+
+ fun newInstance(): MainOptionsBottomSheetDialogFragment {
+ return MainOptionsBottomSheetDialogFragment()
+ }
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveFromPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveFromPlaylistDialog.kt
index 38726666..94988c5a 100644
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveFromPlaylistDialog.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveFromPlaylistDialog.kt
@@ -6,40 +6,17 @@ import android.text.Html
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.widget.TextView
-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.PlaylistSong
import code.name.monkey.retromusic.util.PlaylistsUtil
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
+import kotlinx.android.synthetic.main.dialog_remove_from_playlist.*
import java.util.*
class RemoveFromPlaylistDialog : RoundedBottomSheetDialogFragment() {
- @BindView(R.id.action_remove)
- internal var remove: TextView? = null
-
- @BindView(R.id.title)
- internal var title: TextView? = null
-
- @BindView(R.id.action_cancel)
- internal var cancel: TextView? = null
-
- @OnClick(R.id.action_cancel, R.id.action_remove)
- internal fun actions(view: View) {
- val songs = arguments!!.getParcelableArrayList("songs")
- when (view.id) {
- R.id.action_remove -> {
- if (activity == null)
- return
- PlaylistsUtil.removeFromPlaylist(activity!!, songs!!)
- }
- }
- dismiss()
- }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val layout = inflater.inflate(R.layout.dialog_remove_from_playlist, container, false)
@@ -64,12 +41,17 @@ class RemoveFromPlaylistDialog : RoundedBottomSheetDialogFragment() {
title = R.string.remove_song_from_playlist_title
content = Html.fromHtml(getString(R.string.remove_song_x_from_playlist, songs!![0].title))
}
- this.remove!!.text = content
- this.title!!.setText(title)
+ actionRemove.text = content
+ bannerTitle.setText(title)
- this.title!!.setTextColor(ThemeStore.textColorPrimary(context!!))
- this.remove!!.setTextColor(ThemeStore.textColorSecondary(context!!))
- this.cancel!!.setTextColor(ThemeStore.textColorSecondary(context!!))
+ bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!))
+ actionRemove.setTextColor(ThemeStore.textColorSecondary(context!!))
+ actionCancel.setTextColor(ThemeStore.textColorSecondary(context!!))
+
+ actionRemove.setOnClickListener {
+ PlaylistsUtil.removeFromPlaylist(activity!!, songs)
+ }
+ actionCancel.setOnClickListener { dismiss() }
}
companion object {
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.java
deleted file mode 100644
index 19d32f6c..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package code.name.monkey.retromusic.dialogs;
-
-import android.content.res.ColorStateList;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.google.android.material.button.MaterialButton;
-import com.google.android.material.textfield.TextInputEditText;
-import com.google.android.material.textfield.TextInputLayout;
-
-import java.util.Objects;
-
-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.util.PlaylistsUtil;
-import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment;
-
-public class RenamePlaylistDialog extends RoundedBottomSheetDialogFragment {
-
- @BindView(R.id.title)
- TextView title;
-
- @BindView(R.id.option_1)
- TextInputEditText playlistName;
-
- @BindView(R.id.action_new_playlist)
- TextInputLayout textInputLayout;
-
- @BindView(R.id.action_cancel)
- MaterialButton actionCancel;
-
- @BindView(R.id.action_rename)
- MaterialButton rename;
-
- @NonNull
- public static RenamePlaylistDialog create(long playlistId) {
- RenamePlaylistDialog dialog = new RenamePlaylistDialog();
- Bundle args = new Bundle();
- args.putLong("playlist_id", playlistId);
- dialog.setArguments(args);
- return dialog;
- }
-
- @OnClick({R.id.action_cancel, R.id.action_rename})
- void actions(View view) {
- switch (view.getId()) {
- case R.id.action_cancel:
- dismiss();
- break;
- case R.id.action_rename:
- if (!playlistName.toString().trim().equals("")) {
- long playlistId = getArguments().getLong("playlist_id");
- PlaylistsUtil.renamePlaylist(getActivity(), playlistId,
- playlistName.getText().toString());
- }
- break;
- }
- dismiss();
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View layout = inflater.inflate(R.layout.dialog_playlist_rename, container, false);
- ButterKnife.bind(this, layout);
- return layout;
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- int accentColor = ThemeStore.accentColor(Objects.requireNonNull(getContext()));
- MaterialUtil.setTint(rename,true);
- MaterialUtil.setTint(actionCancel,false);
- MaterialUtil.setTint(textInputLayout,false);
-
- playlistName.setHintTextColor(ColorStateList.valueOf(accentColor));
- playlistName.setTextColor(ThemeStore.textColorPrimary(getContext()));
-
- title.setTextColor(ThemeStore.textColorPrimary(getContext()));
-
- long playlistId = 0;
- if (getArguments() != null) {
- playlistId = getArguments().getLong("playlist_id");
- }
- playlistName.setText(PlaylistsUtil.getNameForPlaylist(getActivity(), playlistId));
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt
new file mode 100644
index 00000000..53bc6cb5
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt
@@ -0,0 +1,65 @@
+package code.name.monkey.retromusic.dialogs
+
+import android.content.res.ColorStateList
+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
+import code.name.monkey.retromusic.util.PlaylistsUtil
+import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
+import kotlinx.android.synthetic.main.dialog_playlist.*
+
+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
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val accentColor = ThemeStore.accentColor(context!!)
+ actionCreate.setText(R.string.action_rename)
+
+ MaterialUtil.setTint(actionCreate, true)
+ MaterialUtil.setTint(actionCancel, false)
+ MaterialUtil.setTint(actionNewPlaylistContainer, false)
+
+ actionNewPlaylist.apply {
+ var playlistId: Long = 0
+ if (arguments != null) {
+ playlistId = arguments!!.getLong("playlist_id")
+ }
+ setText(PlaylistsUtil.getNameForPlaylist(activity!!, playlistId))
+ setHintTextColor(ColorStateList.valueOf(accentColor))
+ setTextColor(ThemeStore.textColorPrimary(context!!))
+ }
+
+ bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!))
+ bannerTitle.setText(R.string.rename_playlist_title)
+ actionCancel.setOnClickListener { dismiss() }
+ actionCreate.setOnClickListener {
+ if (actionNewPlaylist.toString().trim { it <= ' ' } != "") {
+ val playlistId = arguments!!.getLong("playlist_id")
+ PlaylistsUtil.renamePlaylist(context!!, playlistId, actionNewPlaylist.text!!.toString())
+ }
+ }
+ }
+
+ companion object {
+
+ fun create(playlistId: Long): RenamePlaylistDialog {
+ val dialog = RenamePlaylistDialog()
+ val args = Bundle()
+ args.putLong("playlist_id", playlistId)
+ dialog.arguments = args
+ return dialog
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/ArtistGlideRequest.java b/app/src/main/java/code/name/monkey/retromusic/glide/ArtistGlideRequest.java
index 7bf2c1e9..2a779a2a 100644
--- a/app/src/main/java/code/name/monkey/retromusic/glide/ArtistGlideRequest.java
+++ b/app/src/main/java/code/name/monkey/retromusic/glide/ArtistGlideRequest.java
@@ -15,7 +15,7 @@ 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.RetroApplication;
+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;
@@ -31,7 +31,7 @@ public class ArtistGlideRequest {
private static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Artist artist,
boolean noCustomImage, boolean forceDownload) {
- boolean hasCustomImage = CustomArtistImageUtil.getInstance(RetroApplication.Companion.getInstance())
+ boolean hasCustomImage = CustomArtistImageUtil.getInstance(App.Companion.getInstance())
.hasCustomArtistImage(artist);
if (noCustomImage || !hasCustomImage) {
return requestManager.load(new ArtistImage(artist.getName(), forceDownload));
@@ -41,7 +41,7 @@ public class ArtistGlideRequest {
}
private static Key createSignature(Artist artist) {
- return ArtistSignatureUtil.getInstance(RetroApplication.Companion.getInstance())
+ return ArtistSignatureUtil.getInstance(App.Companion.getInstance())
.getArtistSignature(artist.getName());
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt b/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt
index 281dc96a..5defa713 100644
--- a/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/glide/RetroMusicColoredTarget.kt
@@ -7,7 +7,6 @@ import com.bumptech.glide.request.animation.GlideAnimation
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.RetroApplication
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.util.PreferenceUtil
diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt b/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt
index cf685bb2..cec5bd45 100644
--- a/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/helper/MusicPlayerRemote.kt
@@ -12,7 +12,7 @@ import android.provider.MediaStore
import android.util.Log
import android.widget.Toast
import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.RetroApplication
+import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.loaders.SongLoader
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService
@@ -33,7 +33,7 @@ object MusicPlayerRemote {
private val castSession: CastSession?
get() {
- val castSession = CastContext.getSharedInstance(RetroApplication.instance).sessionManager.currentCastSession
+ val castSession = CastContext.getSharedInstance(App.instance).sessionManager.currentCastSession
if (castSession != null) {
playbackLocation = PlaybackLocation.REMOTE
} else {
@@ -48,7 +48,7 @@ object MusicPlayerRemote {
val currentSong: Song
get() = if (musicService != null) {
musicService!!.currentSong
- } else Song.EMPTY_SONG
+ } else Song.emptySong
/**
* Async
diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/menu/GenreMenuHelper.kt b/app/src/main/java/code/name/monkey/retromusic/helper/menu/GenreMenuHelper.kt
index 6796361f..f9c127ce 100644
--- a/app/src/main/java/code/name/monkey/retromusic/helper/menu/GenreMenuHelper.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/helper/menu/GenreMenuHelper.kt
@@ -1,26 +1,22 @@
package code.name.monkey.retromusic.helper.menu
import android.app.Activity
-import androidx.appcompat.app.AppCompatActivity
import android.view.MenuItem
-
-import java.util.ArrayList
-
-import code.name.monkey.retromusic.loaders.GenreLoader
-import code.name.monkey.retromusic.model.Genre
-import code.name.monkey.retromusic.model.Song
+import androidx.appcompat.app.AppCompatActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.loaders.GenreLoader
+import code.name.monkey.retromusic.model.Genre
+import code.name.monkey.retromusic.model.Song
+import java.util.*
/**
* @author Hemanth S (h4h13).
*/
object GenreMenuHelper {
- fun handleMenuClick(activity: AppCompatActivity,
- genre: Genre,
- item: MenuItem): Boolean {
+ fun handleMenuClick(activity: AppCompatActivity, genre: Genre, item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_play -> {
MusicPlayerRemote.openQueue(getGenreSongs(activity, genre), 0, true)
diff --git a/app/src/main/java/code/name/monkey/retromusic/helper/menu/PlaylistMenuHelper.kt b/app/src/main/java/code/name/monkey/retromusic/helper/menu/PlaylistMenuHelper.kt
index 5289ad31..44481a36 100644
--- a/app/src/main/java/code/name/monkey/retromusic/helper/menu/PlaylistMenuHelper.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/helper/menu/PlaylistMenuHelper.kt
@@ -9,7 +9,7 @@ import android.widget.Toast
import java.util.ArrayList
import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.RetroApplication
+import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog
import code.name.monkey.retromusic.dialogs.RenamePlaylistDialog
@@ -76,8 +76,8 @@ object PlaylistMenuHelper {
private class SavePlaylistAsyncTask internal constructor(context: Context) : WeakContextAsyncTask(context) {
override fun doInBackground(vararg params: Playlist): String {
- return String.format(RetroApplication.instance.applicationContext.getString(R.string
- .saved_playlist_to), PlaylistsUtil.savePlaylist(RetroApplication.instance.applicationContext, params[0]).blockingFirst())
+ return String.format(App.instance.applicationContext.getString(R.string
+ .saved_playlist_to), PlaylistsUtil.savePlaylist(App.instance.applicationContext, params[0]).blockingFirst())
}
override fun onPostExecute(string: String) {
diff --git a/app/src/main/java/code/name/monkey/retromusic/loaders/SongLoader.kt b/app/src/main/java/code/name/monkey/retromusic/loaders/SongLoader.kt
index c6e7f40c..9359e339 100644
--- a/app/src/main/java/code/name/monkey/retromusic/loaders/SongLoader.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/loaders/SongLoader.kt
@@ -119,7 +119,7 @@ object SongLoader {
val song: Song = if (cursor != null && cursor.moveToFirst()) {
getSongFromCursorImpl(cursor)
} else {
- Song.EMPTY_SONG
+ Song.emptySong
}
cursor?.close()
e.onNext(song)
diff --git a/app/src/main/java/code/name/monkey/retromusic/model/Album.kt b/app/src/main/java/code/name/monkey/retromusic/model/Album.kt
index 27405c44..dc9df05c 100644
--- a/app/src/main/java/code/name/monkey/retromusic/model/Album.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/model/Album.kt
@@ -36,6 +36,6 @@ class Album {
}
fun safeGetFirstSong(): Song {
- return if (songs!!.isEmpty()) Song.EMPTY_SONG else songs[0]
+ return if (songs!!.isEmpty()) Song.emptySong else songs[0]
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/model/Genre.java b/app/src/main/java/code/name/monkey/retromusic/model/Genre.java
new file mode 100644
index 00000000..9522536d
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/model/Genre.java
@@ -0,0 +1,86 @@
+package code.name.monkey.retromusic.model;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * @author Hemanth S (h4h13).
+ */
+
+public class Genre implements Parcelable {
+
+ public static final Creator CREATOR = new Creator() {
+ @Override
+ public Genre createFromParcel(Parcel in) {
+ return new Genre(in);
+ }
+
+ @Override
+ public Genre[] newArray(int size) {
+ return new Genre[size];
+ }
+ };
+ public final int id;
+ public final String name;
+ public final int songCount;
+
+ public Genre(final int id, final String name, int songCount) {
+ this.id = id;
+ this.name = name;
+ this.songCount = songCount;
+ }
+
+
+ // For unknown genre
+ public Genre(final String name, final int songCount) {
+ this.id = -1;
+ this.name = name;
+ this.songCount = songCount;
+ }
+
+ protected Genre(Parcel in) {
+ id = in.readInt();
+ name = in.readString();
+ songCount = in.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(id);
+ dest.writeString(name);
+ dest.writeInt(songCount);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Genre genre = (Genre) o;
+
+ if (id != genre.id) return false;
+ return name != null ? name.equals(genre.name) : genre.name == null;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = id;
+ result = 31 * result + (name != null ? name.hashCode() : 0);
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "Genre{" +
+ "id=" + id +
+ ", name='" + name + '\'' +
+ '}';
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/model/Genre.kt b/app/src/main/java/code/name/monkey/retromusic/model/Genre.kt
deleted file mode 100644
index 9448e18e..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/model/Genre.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package code.name.monkey.retromusic.model
-
-import java.io.Serializable
-
-/**
- * @author Hemanth S (h4h13).
- */
-
-class Genre : Serializable {
- val id: Int
- val name: String?
- val songCount: Int
-
- constructor(id: Int, name: String, songCount: Int) {
- this.id = id
- this.name = name
- this.songCount = songCount
- }
-
- // For unknown genre
- constructor(name: String, songCount: Int) {
- this.id = -1
- this.name = name
- this.songCount = songCount
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/model/Song.kt b/app/src/main/java/code/name/monkey/retromusic/model/Song.kt
index fab260e2..a395b699 100644
--- a/app/src/main/java/code/name/monkey/retromusic/model/Song.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/model/Song.kt
@@ -64,7 +64,9 @@ open class Song : Parcelable {
}
companion object {
- val EMPTY_SONG = Song(-1, "", -1, -1, -1, "", -1, -1, "", -1, "")
+
+ var emptySong = Song(-1, "", -1, -1, -1, "", -1, -1, "", -1, "")
+
@JvmField
val CREATOR: Parcelable.Creator = object : Parcelable.Creator {
override fun createFromParcel(source: Parcel): Song {
diff --git a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.java b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.java
index 0885f68a..c09e12fc 100644
--- a/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.java
+++ b/app/src/main/java/code/name/monkey/retromusic/mvp/presenter/ArtistDetailsPresenter.java
@@ -1,13 +1,12 @@
package code.name.monkey.retromusic.mvp.presenter;
import android.os.Bundle;
-import androidx.annotation.NonNull;
+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 static code.name.monkey.retromusic.ui.activities.ArtistDetailActivity.EXTRA_ARTIST_ID;
+import code.name.monkey.retromusic.ui.activities.ArtistDetailActivity;
/**
@@ -38,7 +37,7 @@ public class ArtistDetailsPresenter extends Presenter implements ArtistDetailCon
@Override
public void loadArtistById() {
- disposable.add(repository.getArtistById(bundle.getInt(EXTRA_ARTIST_ID))
+ disposable.add(repository.getArtistById(bundle.getInt(ArtistDetailActivity.EXTRA_ARTIST_ID))
.subscribeOn(schedulerProvider.computation())
.observeOn(schedulerProvider.ui())
.doOnSubscribe(disposable1 -> view.loading())
diff --git a/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.java b/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.java
index 6c68c8ca..59d7fde5 100644
--- a/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.java
+++ b/app/src/main/java/code/name/monkey/retromusic/preferences/NowPlayingScreenPreferenceDialog.java
@@ -21,7 +21,7 @@ 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.RetroApplication;
+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;
@@ -97,8 +97,8 @@ public class NowPlayingScreenPreferenceDialog extends DialogFragment implements
nowPlayingScreen.equals(NowPlayingScreen.TINY) ||
nowPlayingScreen.equals(NowPlayingScreen.BLUR_CARD)||
nowPlayingScreen.equals(NowPlayingScreen.ADAPTIVE))
- && !RetroApplication.Companion.isProVersion();*/
- return !RetroApplication.Companion.isProVersion();
+ && !App.Companion.isProVersion();*/
+ return !App.Companion.isProVersion();
}
@Override
diff --git a/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.java b/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.java
index 7deda91e..d65c7b6b 100644
--- a/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.java
+++ b/app/src/main/java/code/name/monkey/retromusic/providers/RepositoryImpl.java
@@ -6,7 +6,7 @@ import java.io.File;
import java.util.ArrayList;
import code.name.monkey.retromusic.Injection;
-import code.name.monkey.retromusic.RetroApplication;
+import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.loaders.AlbumLoader;
import code.name.monkey.retromusic.loaders.ArtistLoader;
import code.name.monkey.retromusic.loaders.GenreLoader;
@@ -41,7 +41,7 @@ public class RepositoryImpl implements Repository {
public static synchronized RepositoryImpl getInstance() {
if (INSTANCE == null) {
- INSTANCE = new RepositoryImpl(RetroApplication.Companion.getInstance());
+ INSTANCE = new RepositoryImpl(App.Companion.getInstance());
}
return INSTANCE;
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/rest/KogouClient.java b/app/src/main/java/code/name/monkey/retromusic/rest/KogouClient.java
index fcf0c7cd..dca902fa 100644
--- a/app/src/main/java/code/name/monkey/retromusic/rest/KogouClient.java
+++ b/app/src/main/java/code/name/monkey/retromusic/rest/KogouClient.java
@@ -6,7 +6,7 @@ import java.io.File;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import code.name.monkey.retromusic.RetroApplication;
+import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.rest.service.KuGouApiService;
import okhttp3.Cache;
import okhttp3.Call;
@@ -69,7 +69,7 @@ public class KogouClient {
return new OkHttpClient.Builder()
.addInterceptor(interceptor)
- .cache(createDefaultCache(RetroApplication.Companion.getInstance()))
+ .cache(createDefaultCache(App.Companion.getInstance()))
.addInterceptor(createCacheControlInterceptor());
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.java b/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.java
new file mode 100644
index 00000000..d725f40b
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.java
@@ -0,0 +1,334 @@
+package code.name.monkey.retromusic.service;
+
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.media.audiofx.AudioEffect;
+import android.net.Uri;
+import android.os.PowerManager;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import android.util.Log;
+import android.widget.Toast;
+
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.service.playback.Playback;
+import code.name.monkey.retromusic.util.PreferenceUtil;
+
+/**
+ * @author Andrew Neal, Karim Abou Zeid (kabouzeid)
+ */
+public class MultiPlayer implements Playback, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
+ public static final String TAG = MultiPlayer.class.getSimpleName();
+
+ private MediaPlayer mCurrentMediaPlayer = new MediaPlayer();
+ private MediaPlayer mNextMediaPlayer;
+
+ private Context context;
+ @Nullable
+ private Playback.PlaybackCallbacks callbacks;
+
+ private boolean mIsInitialized = false;
+
+ /**
+ * Constructor of MultiPlayer
+ */
+ MultiPlayer(final Context context) {
+ this.context = context;
+ mCurrentMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK);
+ }
+
+ /**
+ * @param path The path of the file, or the http/rtsp URL of the stream
+ * you want to play
+ * @return True if the player
has been prepared and is
+ * ready to play, false otherwise
+ */
+ @Override
+ public boolean setDataSource(@NonNull final String path) {
+ mIsInitialized = false;
+ mIsInitialized = setDataSourceImpl(mCurrentMediaPlayer, path);
+ if (mIsInitialized) {
+ setNextDataSource(null);
+ }
+ return mIsInitialized;
+ }
+
+ /**
+ * @param player The {@link MediaPlayer} to use
+ * @param path The path of the file, or the http/rtsp URL of the stream
+ * you want to play
+ * @return True if the player
has been prepared and is
+ * ready to play, false otherwise
+ */
+ private boolean setDataSourceImpl(@NonNull final MediaPlayer player, @NonNull final String path) {
+ if (context == null) {
+ return false;
+ }
+ try {
+ player.reset();
+ player.setOnPreparedListener(null);
+ if (path.startsWith("content://")) {
+ player.setDataSource(context, Uri.parse(path));
+ } else {
+ player.setDataSource(path);
+ }
+ player.setAudioStreamType(AudioManager.STREAM_MUSIC);
+ player.prepare();
+ } catch (Exception e) {
+ return false;
+ }
+ player.setOnCompletionListener(this);
+ player.setOnErrorListener(this);
+ final Intent intent = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
+ intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, getAudioSessionId());
+ intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.getPackageName());
+ intent.putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC);
+ context.sendBroadcast(intent);
+ return true;
+ }
+
+ /**
+ * Set the MediaPlayer to start when this MediaPlayer finishes playback.
+ *
+ * @param path The path of the file, or the http/rtsp URL of the stream
+ * you want to play
+ */
+ @Override
+ public void setNextDataSource(@Nullable final String path) {
+ if (context == null) {
+ return;
+ }
+ try {
+ mCurrentMediaPlayer.setNextMediaPlayer(null);
+ } catch (IllegalArgumentException e) {
+ Log.i(TAG, "Next media player is current one, continuing");
+ } catch (IllegalStateException e) {
+ Log.e(TAG, "Media player not initialized!");
+ return;
+ }
+ if (mNextMediaPlayer != null) {
+ mNextMediaPlayer.release();
+ mNextMediaPlayer = null;
+ }
+ if (path == null) {
+ return;
+ }
+ if (PreferenceUtil.getInstance().gaplessPlayback()) {
+ mNextMediaPlayer = new MediaPlayer();
+ mNextMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK);
+ mNextMediaPlayer.setAudioSessionId(getAudioSessionId());
+ if (setDataSourceImpl(mNextMediaPlayer, path)) {
+ try {
+ mCurrentMediaPlayer.setNextMediaPlayer(mNextMediaPlayer);
+ } catch (@NonNull IllegalArgumentException | IllegalStateException e) {
+ Log.e(TAG, "setNextDataSource: setNextMediaPlayer()", e);
+ if (mNextMediaPlayer != null) {
+ mNextMediaPlayer.release();
+ mNextMediaPlayer = null;
+ }
+ }
+ } else {
+ if (mNextMediaPlayer != null) {
+ mNextMediaPlayer.release();
+ mNextMediaPlayer = null;
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets the callbacks
+ *
+ * @param callbacks The callbacks to use
+ */
+ @Override
+ public void setCallbacks(@Nullable final Playback.PlaybackCallbacks callbacks) {
+ this.callbacks = callbacks;
+ }
+
+ /**
+ * @return True if the player is ready to go, false otherwise
+ */
+ @Override
+ public boolean isInitialized() {
+ return mIsInitialized;
+ }
+
+ /**
+ * Starts or resumes playback.
+ */
+ @Override
+ public boolean start() {
+ try {
+ mCurrentMediaPlayer.start();
+ return true;
+ } catch (IllegalStateException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Resets the MediaPlayer to its uninitialized state.
+ */
+ @Override
+ public void stop() {
+ mCurrentMediaPlayer.reset();
+ mIsInitialized = false;
+ }
+
+ /**
+ * Releases resources associated with this MediaPlayer object.
+ */
+ @Override
+ public void release() {
+ stop();
+ mCurrentMediaPlayer.release();
+ if (mNextMediaPlayer != null) {
+ mNextMediaPlayer.release();
+ }
+ }
+
+ /**
+ * Pauses playback. Call start() to resume.
+ */
+ @Override
+ public boolean pause() {
+ try {
+ mCurrentMediaPlayer.pause();
+ return true;
+ } catch (IllegalStateException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Checks whether the MultiPlayer is playing.
+ */
+ @Override
+ public boolean isPlaying() {
+ return mIsInitialized && mCurrentMediaPlayer.isPlaying();
+ }
+
+ /**
+ * Gets the duration of the file.
+ *
+ * @return The duration in milliseconds
+ */
+ @Override
+ public int duration() {
+ if (!mIsInitialized) {
+ return -1;
+ }
+ try {
+ return mCurrentMediaPlayer.getDuration();
+ } catch (IllegalStateException e) {
+ return -1;
+ }
+ }
+
+ /**
+ * Gets the current playback position.
+ *
+ * @return The current position in milliseconds
+ */
+ @Override
+ public int position() {
+ if (!mIsInitialized) {
+ return -1;
+ }
+ try {
+ return mCurrentMediaPlayer.getCurrentPosition();
+ } catch (IllegalStateException e) {
+ return -1;
+ }
+ }
+
+ /**
+ * Gets the current playback position.
+ *
+ * @param whereto The offset in milliseconds from the start to seek to
+ * @return The offset in milliseconds from the start to seek to
+ */
+ @Override
+ public int seek(final int whereto) {
+ try {
+ mCurrentMediaPlayer.seekTo(whereto);
+ return whereto;
+ } catch (IllegalStateException e) {
+ return -1;
+ }
+ }
+
+ @Override
+ public boolean setVolume(final float vol) {
+ try {
+ mCurrentMediaPlayer.setVolume(vol, vol);
+ return true;
+ } catch (IllegalStateException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Sets the audio session ID.
+ *
+ * @param sessionId The audio session ID
+ */
+ @Override
+ public boolean setAudioSessionId(final int sessionId) {
+ try {
+ mCurrentMediaPlayer.setAudioSessionId(sessionId);
+ return true;
+ } catch (@NonNull IllegalArgumentException | IllegalStateException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Returns the audio session ID.
+ *
+ * @return The current audio session ID.
+ */
+ @Override
+ public int getAudioSessionId() {
+ return mCurrentMediaPlayer.getAudioSessionId();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean onError(final MediaPlayer mp, final int what, final int extra) {
+ mIsInitialized = false;
+ mCurrentMediaPlayer.release();
+ mCurrentMediaPlayer = new MediaPlayer();
+ mCurrentMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK);
+ if (context != null) {
+ Toast.makeText(context, context.getResources().getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show();
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onCompletion(final MediaPlayer mp) {
+ if (mp == mCurrentMediaPlayer && mNextMediaPlayer != null) {
+ mIsInitialized = false;
+ mCurrentMediaPlayer.release();
+ mCurrentMediaPlayer = mNextMediaPlayer;
+ mIsInitialized = true;
+ mNextMediaPlayer = null;
+ if (callbacks != null)
+ callbacks.onTrackWentToNext();
+ } else {
+ if (callbacks != null)
+ callbacks.onTrackEnded();
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt b/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt
deleted file mode 100644
index ba24b958..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/service/MultiPlayer.kt
+++ /dev/null
@@ -1,333 +0,0 @@
-package code.name.monkey.retromusic.service
-
-import android.content.Context
-import android.content.Intent
-import android.media.AudioManager
-import android.media.MediaPlayer
-import android.media.audiofx.AudioEffect
-import android.net.Uri
-import android.os.PowerManager
-import android.util.Log
-import android.widget.Toast
-
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.service.playback.Playback
-import code.name.monkey.retromusic.util.PreferenceUtil
-
-/**
- * @author Andrew Neal, Karim Abou Zeid (kabouzeid)
- */
-class MultiPlayer
-/**
- * Constructor of `MultiPlayer`
- */
-internal constructor(private val context: Context?) : Playback, MediaPlayer.OnErrorListener, MediaPlayer.OnCompletionListener {
-
- private var mCurrentMediaPlayer = MediaPlayer()
- private var mNextMediaPlayer: MediaPlayer? = null
- private var callbacks: Playback.PlaybackCallbacks? = null
-
- private var mIsInitialized = false
-
- init {
- mCurrentMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK)
- }
-
- /**
- * @param path The path of the file, or the http/rtsp URL of the stream
- * you want to play
- * @return True if the `player` has been prepared and is
- * ready to play, false otherwise
- */
- override fun setDataSource(path: String): Boolean {
- mIsInitialized = false
- mIsInitialized = setDataSourceImpl(mCurrentMediaPlayer, path)
- if (mIsInitialized) {
- setNextDataSource(null)
- }
- return mIsInitialized
- }
-
- /**
- * @param player The [MediaPlayer] to use
- * @param path The path of the file, or the http/rtsp URL of the stream
- * you want to play
- * @return True if the `player` has been prepared and is
- * ready to play, false otherwise
- */
- private fun setDataSourceImpl(player: MediaPlayer, path: String): Boolean {
- if (context == null) {
- return false
- }
- try {
- player.reset()
- player.setOnPreparedListener(null)
- if (path.startsWith("content://")) {
- player.setDataSource(context, Uri.parse(path))
- } else {
- player.setDataSource(path)
- }
- player.setAudioStreamType(AudioManager.STREAM_MUSIC)
- player.prepare()
- } catch (e: Exception) {
- return false
- }
-
- player.setOnCompletionListener(this)
- player.setOnErrorListener(this)
- val intent = Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION)
- intent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, audioSessionId)
- intent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, context.packageName)
- intent.putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC)
- context.sendBroadcast(intent)
- return true
- }
-
- /**
- * Set the MediaPlayer to start when this MediaPlayer finishes playback.
- *
- * @param path The path of the file, or the http/rtsp URL of the stream
- * you want to play
- */
- override fun setNextDataSource(path: String?) {
- if (context == null) {
- return
- }
- try {
- mCurrentMediaPlayer.setNextMediaPlayer(null)
- } catch (e: IllegalArgumentException) {
- Log.i(TAG, "Next media player is current one, continuing")
- } catch (e: IllegalStateException) {
- Log.e(TAG, "Media player not initialized!")
- return
- }
-
- if (mNextMediaPlayer != null) {
- mNextMediaPlayer!!.release()
- mNextMediaPlayer = null
- }
- if (path == null) {
- return
- }
- if (PreferenceUtil.getInstance().gaplessPlayback()) {
- mNextMediaPlayer = MediaPlayer()
- mNextMediaPlayer!!.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK)
- mNextMediaPlayer!!.audioSessionId = audioSessionId
- if (setDataSourceImpl(mNextMediaPlayer!!, path)) {
- try {
- mCurrentMediaPlayer.setNextMediaPlayer(mNextMediaPlayer)
- } catch (e: IllegalArgumentException) {
- Log.e(TAG, "setNextDataSource: setNextMediaPlayer()", e)
- if (mNextMediaPlayer != null) {
- mNextMediaPlayer!!.release()
- mNextMediaPlayer = null
- }
- } catch (e: IllegalStateException) {
- Log.e(TAG, "setNextDataSource: setNextMediaPlayer()", e)
- if (mNextMediaPlayer != null) {
- mNextMediaPlayer!!.release()
- mNextMediaPlayer = null
- }
- }
-
- } else {
- if (mNextMediaPlayer != null) {
- mNextMediaPlayer!!.release()
- mNextMediaPlayer = null
- }
- }
- }
- }
-
- /**
- * Sets the callbacks
- *
- * @param callbacks The callbacks to use
- */
- override fun setCallbacks(callbacks: Playback.PlaybackCallbacks?) {
- this.callbacks = callbacks
- }
-
- /**
- * @return True if the player is ready to go, false otherwise
- */
- override fun isInitialized(): Boolean {
- return mIsInitialized
- }
-
- /**
- * Starts or resumes playback.
- */
- override fun start(): Boolean {
- try {
- mCurrentMediaPlayer.start()
- return true
- } catch (e: IllegalStateException) {
- return false
- }
-
- }
-
- /**
- * Resets the MediaPlayer to its uninitialized state.
- */
- override fun stop() {
- mCurrentMediaPlayer.reset()
- mIsInitialized = false
- }
-
- /**
- * Releases resources associated with this MediaPlayer object.
- */
- override fun release() {
- stop()
- mCurrentMediaPlayer.release()
- if (mNextMediaPlayer != null) {
- mNextMediaPlayer!!.release()
- }
- }
-
- /**
- * Pauses playback. Call start() to resume.
- */
- override fun pause(): Boolean {
- try {
- mCurrentMediaPlayer.pause()
- return true
- } catch (e: IllegalStateException) {
- return false
- }
-
- }
-
- /**
- * Checks whether the MultiPlayer is playing.
- */
- override fun isPlaying(): Boolean {
- return mIsInitialized && mCurrentMediaPlayer.isPlaying
- }
-
- /**
- * Gets the duration of the file.
- *
- * @return The duration in milliseconds
- */
- override fun duration(): Int {
- if (!mIsInitialized) {
- return -1
- }
- try {
- return mCurrentMediaPlayer.duration
- } catch (e: IllegalStateException) {
- return -1
- }
-
- }
-
- /**
- * Gets the current playback position.
- *
- * @return The current position in milliseconds
- */
- override fun position(): Int {
- if (!mIsInitialized) {
- return -1
- }
- try {
- return mCurrentMediaPlayer.currentPosition
- } catch (e: IllegalStateException) {
- return -1
- }
-
- }
-
- /**
- * Gets the current playback position.
- *
- * @param whereto The offset in milliseconds from the start to seek to
- * @return The offset in milliseconds from the start to seek to
- */
- override fun seek(whereto: Int): Int {
- try {
- mCurrentMediaPlayer.seekTo(whereto)
- return whereto
- } catch (e: IllegalStateException) {
- return -1
- }
-
- }
-
- override fun setVolume(vol: Float): Boolean {
- try {
- mCurrentMediaPlayer.setVolume(vol, vol)
- return true
- } catch (e: IllegalStateException) {
- return false
- }
-
- }
-
- /**
- * Sets the audio session ID.
- *
- * @param sessionId The audio session ID
- */
- override fun setAudioSessionId(sessionId: Int): Boolean {
- try {
- mCurrentMediaPlayer.audioSessionId = sessionId
- return true
- } catch (e: IllegalArgumentException) {
- return false
- } catch (e: IllegalStateException) {
- return false
- }
-
- }
-
- /**
- * Returns the audio session ID.
- *
- * @return The current audio session ID.
- */
- override fun getAudioSessionId(): Int {
- return mCurrentMediaPlayer.audioSessionId
- }
-
- /**
- * {@inheritDoc}
- */
- override fun onError(mp: MediaPlayer, what: Int, extra: Int): Boolean {
- mIsInitialized = false
- mCurrentMediaPlayer.release()
- mCurrentMediaPlayer = MediaPlayer()
- mCurrentMediaPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK)
- if (context != null) {
- Toast.makeText(context, context.resources.getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show()
- }
- return false
- }
-
- /**
- * {@inheritDoc}
- */
- override fun onCompletion(mp: MediaPlayer) {
- if (mp === mCurrentMediaPlayer && mNextMediaPlayer != null) {
- mIsInitialized = false
- mCurrentMediaPlayer.release()
- mCurrentMediaPlayer = mNextMediaPlayer as MediaPlayer
- mIsInitialized = true
- mNextMediaPlayer = null
- if (callbacks != null)
- callbacks!!.onTrackWentToNext()
- } else {
- if (callbacks != null)
- callbacks!!.onTrackEnded()
- }
- }
-
- companion object {
- val TAG: String = MultiPlayer::class.java.simpleName
- }
-
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java
new file mode 100644
index 00000000..39d4e0f0
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.java
@@ -0,0 +1,1420 @@
+package code.name.monkey.retromusic.service;
+
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.database.ContentObserver;
+import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.graphics.drawable.Drawable;
+import android.media.AudioManager;
+import android.media.audiofx.AudioEffect;
+import android.media.session.MediaSession;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.Process;
+import android.preference.PreferenceManager;
+import android.provider.MediaStore;
+import android.support.v4.media.MediaMetadataCompat;
+import android.support.v4.media.session.MediaSessionCompat;
+import android.support.v4.media.session.PlaybackStateCompat;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.bumptech.glide.BitmapRequestBuilder;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.request.animation.GlideAnimation;
+import com.bumptech.glide.request.target.SimpleTarget;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import code.name.monkey.retromusic.R;
+import code.name.monkey.retromusic.glide.BlurTransformation;
+import code.name.monkey.retromusic.glide.SongGlideRequest;
+import code.name.monkey.retromusic.helper.ShuffleHelper;
+import code.name.monkey.retromusic.helper.StopWatch;
+import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
+import code.name.monkey.retromusic.model.AbsCustomPlaylist;
+import code.name.monkey.retromusic.model.Playlist;
+import code.name.monkey.retromusic.model.Song;
+import code.name.monkey.retromusic.providers.HistoryStore;
+import code.name.monkey.retromusic.providers.MusicPlaybackQueueStore;
+import code.name.monkey.retromusic.providers.SongPlayCountStore;
+import code.name.monkey.retromusic.service.notification.PlayingNotification;
+import code.name.monkey.retromusic.service.notification.PlayingNotificationImpl24;
+import code.name.monkey.retromusic.service.notification.PlayingNotificationOreo;
+import code.name.monkey.retromusic.service.playback.Playback;
+import code.name.monkey.retromusic.util.MusicUtil;
+import code.name.monkey.retromusic.util.PreferenceUtil;
+import code.name.monkey.retromusic.util.RetroUtil;
+
+import static code.name.monkey.retromusic.Constants.ACTION_PAUSE;
+import static code.name.monkey.retromusic.Constants.ACTION_PLAY;
+import static code.name.monkey.retromusic.Constants.ACTION_PLAY_PLAYLIST;
+import static code.name.monkey.retromusic.Constants.ACTION_QUIT;
+import static code.name.monkey.retromusic.Constants.ACTION_REWIND;
+import static code.name.monkey.retromusic.Constants.ACTION_SKIP;
+import static code.name.monkey.retromusic.Constants.ACTION_STOP;
+import static code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE;
+import static code.name.monkey.retromusic.Constants.APP_WIDGET_UPDATE;
+import static code.name.monkey.retromusic.Constants.EXTRA_APP_WIDGET_NAME;
+import static code.name.monkey.retromusic.Constants.INTENT_EXTRA_PLAYLIST;
+import static code.name.monkey.retromusic.Constants.INTENT_EXTRA_SHUFFLE_MODE;
+import static code.name.monkey.retromusic.Constants.MEDIA_STORE_CHANGED;
+import static code.name.monkey.retromusic.Constants.META_CHANGED;
+import static code.name.monkey.retromusic.Constants.MUSIC_PACKAGE_NAME;
+import static code.name.monkey.retromusic.Constants.PLAY_STATE_CHANGED;
+import static code.name.monkey.retromusic.Constants.QUEUE_CHANGED;
+import static code.name.monkey.retromusic.Constants.REPEAT_MODE_CHANGED;
+import static code.name.monkey.retromusic.Constants.RETRO_MUSIC_PACKAGE_NAME;
+import static code.name.monkey.retromusic.Constants.SHUFFLE_MODE_CHANGED;
+
+/**
+ * @author Karim Abou Zeid (kabouzeid), Andrew Neal
+ */
+public class MusicService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener, Playback.PlaybackCallbacks {
+ public static final String TAG = MusicService.class.getSimpleName();
+
+ public static final String SAVED_POSITION = "POSITION";
+ public static final String SAVED_POSITION_IN_TRACK = "POSITION_IN_TRACK";
+ public static final String SAVED_SHUFFLE_MODE = "SHUFFLE_MODE";
+ public static final String SAVED_REPEAT_MODE = "REPEAT_MODE";
+
+ public static final int RELEASE_WAKELOCK = 0;
+ public static final int TRACK_ENDED = 1;
+ public static final int TRACK_WENT_TO_NEXT = 2;
+ public static final int PLAY_SONG = 3;
+ public static final int PREPARE_NEXT = 4;
+ public static final int SET_POSITION = 5;
+ public static final int RESTORE_QUEUES = 9;
+ public static final int SHUFFLE_MODE_NONE = 0;
+ public static final int SHUFFLE_MODE_SHUFFLE = 1;
+ public static final int REPEAT_MODE_NONE = 0;
+ public static final int REPEAT_MODE_ALL = 1;
+ public static final int REPEAT_MODE_THIS = 2;
+ public static final int SAVE_QUEUES = 0;
+ private static final int FOCUS_CHANGE = 6;
+ private static final int DUCK = 7;
+ private static final int UNDUCK = 8;
+ private static final long MEDIA_SESSION_ACTIONS = PlaybackStateCompat.ACTION_PLAY
+ | PlaybackStateCompat.ACTION_PAUSE
+ | PlaybackStateCompat.ACTION_PLAY_PAUSE
+ | PlaybackStateCompat.ACTION_SKIP_TO_NEXT
+ | PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
+ | PlaybackStateCompat.ACTION_STOP
+ | PlaybackStateCompat.ACTION_SEEK_TO;
+ private final IBinder musicBind = new MusicBinder();
+ private final BroadcastReceiver widgetIntentReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(final Context context, final Intent intent) {
+ final String command = intent.getStringExtra(EXTRA_APP_WIDGET_NAME);
+
+ }
+ };
+ private Playback playback;
+ private ArrayList playingQueue = new ArrayList<>();
+ private ArrayList originalPlayingQueue = new ArrayList<>();
+ private int position = -1;
+ private int nextPosition = -1;
+ private int shuffleMode;
+ private int repeatMode;
+ private boolean queuesRestored;
+ private boolean pausedByTransientLossOfFocus;
+ private final BroadcastReceiver becomingNoisyReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, @NonNull Intent intent) {
+ if (intent.getAction() != null && intent.getAction().equals(AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
+ pause();
+ }
+ }
+ };
+ private PlayingNotification playingNotification;
+ private AudioManager audioManager;
+ @SuppressWarnings("deprecation")
+ private MediaSessionCompat mediaSession;
+ private PowerManager.WakeLock wakeLock;
+ private PlaybackHandler playerHandler;
+ private final AudioManager.OnAudioFocusChangeListener audioFocusListener = new AudioManager.OnAudioFocusChangeListener() {
+ @Override
+ public void onAudioFocusChange(final int focusChange) {
+ playerHandler.obtainMessage(FOCUS_CHANGE, focusChange, 0).sendToTarget();
+ }
+ };
+ private QueueSaveHandler queueSaveHandler;
+ private HandlerThread musicPlayerHandlerThread;
+ private HandlerThread queueSaveHandlerThread;
+ private SongPlayCountHelper songPlayCountHelper = new SongPlayCountHelper();
+ private ThrottledSeekHandler throttledSeekHandler;
+ private boolean becomingNoisyReceiverRegistered;
+ private IntentFilter becomingNoisyReceiverIntentFilter = new IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY);
+ private ContentObserver mediaStoreObserver;
+ private boolean notHandledMetaChangedForCurrentTrack;
+ private PhoneStateListener phoneStateListener = new PhoneStateListener() {
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
+ switch (state) {
+ case TelephonyManager.CALL_STATE_IDLE:
+ //Not in call: Play music
+ play();
+ break;
+ case TelephonyManager.CALL_STATE_RINGING:
+ case TelephonyManager.CALL_STATE_OFFHOOK:
+ //A call is dialing, active or on hold
+ pause();
+ break;
+ default:
+ }
+ super.onCallStateChanged(state, incomingNumber);
+ }
+ };
+ private boolean isServiceBound;
+ private Handler uiThreadHandler;
+ private IntentFilter headsetReceiverIntentFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
+ private boolean headsetReceiverRegistered = false;
+ private BroadcastReceiver headsetReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action != null) {
+ switch (action) {
+ case Intent.ACTION_HEADSET_PLUG:
+ int state = intent.getIntExtra("state", -1);
+ switch (state) {
+ case 0:
+ Log.d(TAG, "Headset unplugged");
+ pause();
+ break;
+ case 1:
+ Log.d(TAG, "Headset plugged");
+ play();
+ break;
+ }
+ break;
+ }
+ }
+ }
+ };
+
+ private static String getTrackUri(@NonNull Song song) {
+ return MusicUtil.getSongFileUri(song.getId()).toString();
+ }
+
+ private static Bitmap copy(Bitmap bitmap) {
+ Bitmap.Config config = bitmap.getConfig();
+ if (config == null) {
+ config = Bitmap.Config.RGB_565;
+ }
+ try {
+ return bitmap.copy(config, false);
+ } catch (OutOfMemoryError e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ final TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
+ if (telephonyManager != null) {
+ telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
+ }
+
+ final PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+ if (powerManager != null) {
+ wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, getClass().getName());
+ }
+ wakeLock.setReferenceCounted(false);
+
+ musicPlayerHandlerThread = new HandlerThread("PlaybackHandler");
+ musicPlayerHandlerThread.start();
+ playerHandler = new PlaybackHandler(this, musicPlayerHandlerThread.getLooper());
+
+ playback = new MultiPlayer(this);
+ playback.setCallbacks(this);
+
+ setupMediaSession();
+
+ // queue saving needs to run on a separate thread so that it doesn't block the playback handler events
+ queueSaveHandlerThread = new HandlerThread("QueueSaveHandler", Process.THREAD_PRIORITY_BACKGROUND);
+ queueSaveHandlerThread.start();
+ queueSaveHandler = new QueueSaveHandler(this, queueSaveHandlerThread.getLooper());
+
+ uiThreadHandler = new Handler();
+
+ registerReceiver(widgetIntentReceiver, new IntentFilter(APP_WIDGET_UPDATE));
+
+ initNotification();
+
+ mediaStoreObserver = new MediaStoreObserver(playerHandler);
+ throttledSeekHandler = new ThrottledSeekHandler(playerHandler);
+ getContentResolver().registerContentObserver(
+ MediaStore.Audio.Media.INTERNAL_CONTENT_URI, true, mediaStoreObserver);
+ getContentResolver().registerContentObserver(
+ MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, mediaStoreObserver);
+
+ PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this);
+
+ restoreState();
+
+ mediaSession.setActive(true);
+
+ sendBroadcast(new Intent("code.name.monkey.retromusic.RETRO_MUSIC_SERVICE_CREATED"));
+
+ registerHeadsetEvents();
+
+
+ }
+
+ private AudioManager getAudioManager() {
+ if (audioManager == null) {
+ audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ }
+ return audioManager;
+ }
+
+ private void setupMediaSession() {
+ ComponentName mediaButtonReceiverComponentName = new ComponentName(getApplicationContext(), MediaButtonIntentReceiver.class);
+
+ Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ mediaButtonIntent.setComponent(mediaButtonReceiverComponentName);
+
+
+ PendingIntent mediaButtonReceiverPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
+
+ mediaSession = new MediaSessionCompat(this, "RetroMusicPlayer", mediaButtonReceiverComponentName, mediaButtonReceiverPendingIntent);
+ mediaSession.setCallback(new MediaSessionCompat.Callback() {
+ @Override
+ public void onPlay() {
+ play();
+ }
+
+ @Override
+ public void onPause() {
+ pause();
+ }
+
+ @Override
+ public void onSkipToNext() {
+ playNextSong(true);
+ }
+
+ @Override
+ public void onSkipToPrevious() {
+ back(true);
+ }
+
+ @Override
+ public void onStop() {
+ quit();
+ }
+
+ @Override
+ public void onSeekTo(long pos) {
+ seek((int) pos);
+ }
+
+ @Override
+ public boolean onMediaButtonEvent(Intent mediaButtonEvent) {
+ return MediaButtonIntentReceiver.Companion.handleIntent(MusicService.this, mediaButtonEvent);
+ }
+ });
+
+ mediaSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS
+ | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS);
+
+ mediaSession.setMediaButtonReceiver(mediaButtonReceiverPendingIntent);
+ }
+
+ @Override
+ public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
+ if (intent != null) {
+ if (intent.getAction() != null) {
+ restoreQueuesAndPositionIfNecessary();
+ String action = intent.getAction();
+ switch (action) {
+ case ACTION_TOGGLE_PAUSE:
+ if (isPlaying()) {
+ pause();
+ } else {
+ play();
+ }
+ break;
+ case ACTION_PAUSE:
+ pause();
+ break;
+ case ACTION_PLAY:
+ play();
+ break;
+ case ACTION_PLAY_PLAYLIST:
+ Playlist playlist = intent.getParcelableExtra(INTENT_EXTRA_PLAYLIST);
+ int shuffleMode = intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, getShuffleMode());
+ if (playlist != null) {
+ ArrayList playlistSongs;
+ if (playlist instanceof AbsCustomPlaylist) {
+ playlistSongs = ((AbsCustomPlaylist) playlist).getSongs(getApplicationContext()).blockingFirst();
+ } else {
+ //noinspection unchecked
+ playlistSongs = PlaylistSongsLoader.INSTANCE.getPlaylistSongList(getApplicationContext(), playlist.id).blockingFirst();
+ }
+ if (!playlistSongs.isEmpty()) {
+ if (shuffleMode == SHUFFLE_MODE_SHUFFLE) {
+ int startPosition;
+ startPosition = new Random().nextInt(playlistSongs.size());
+ openQueue(playlistSongs, startPosition, true);
+ setShuffleMode(shuffleMode);
+ } else {
+ openQueue(playlistSongs, 0, true);
+ }
+ } else {
+ Toast.makeText(getApplicationContext(), R.string.playlist_is_empty, Toast.LENGTH_LONG).show();
+ }
+ } else {
+ Toast.makeText(getApplicationContext(), R.string.playlist_is_empty, Toast.LENGTH_LONG).show();
+ }
+ break;
+ case ACTION_REWIND:
+ back(true);
+ break;
+ case ACTION_SKIP:
+ playNextSong(true);
+ break;
+ case ACTION_STOP:
+ case ACTION_QUIT:
+ return quit();
+ }
+ }
+ }
+
+ return START_STICKY;
+ }
+
+
+ @Override
+ public void onDestroy() {
+ unregisterReceiver(widgetIntentReceiver);
+ if (becomingNoisyReceiverRegistered) {
+ unregisterReceiver(becomingNoisyReceiver);
+ becomingNoisyReceiverRegistered = false;
+ }
+ if (headsetReceiverRegistered) {
+ unregisterReceiver(headsetReceiver);
+ headsetReceiverRegistered = false;
+ }
+ mediaSession.setActive(false);
+ quit();
+ releaseResources();
+ getContentResolver().unregisterContentObserver(mediaStoreObserver);
+ PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this);
+ wakeLock.release();
+
+ sendBroadcast(new Intent("code.name.monkey.retromusic.RETRO_MUSIC_MUSIC_SERVICE_DESTROYED"));
+ }
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ isServiceBound = true;
+ return musicBind;
+ }
+
+ @Override
+ public void onRebind(Intent intent) {
+ isServiceBound = true;
+ }
+
+ @Override
+ public boolean onUnbind(Intent intent) {
+ isServiceBound = false;
+ if (!isPlaying()) {
+ stopSelf();
+ }
+ return true;
+ }
+
+ private void saveQueuesImpl() {
+ MusicPlaybackQueueStore.getInstance(this).saveQueues(playingQueue, originalPlayingQueue);
+ }
+
+ private void savePosition() {
+ PreferenceManager.getDefaultSharedPreferences(this).edit().putInt(SAVED_POSITION, getPosition()).apply();
+ }
+
+ private void savePositionInTrack() {
+ PreferenceManager.getDefaultSharedPreferences(this).edit().putInt(SAVED_POSITION_IN_TRACK, getSongProgressMillis()).apply();
+ }
+
+ public void saveState() {
+ saveQueues();
+ savePosition();
+ savePositionInTrack();
+ }
+
+ private void saveQueues() {
+ queueSaveHandler.removeMessages(SAVE_QUEUES);
+ queueSaveHandler.sendEmptyMessage(SAVE_QUEUES);
+ }
+
+ private void restoreState() {
+ shuffleMode = PreferenceManager.getDefaultSharedPreferences(this).getInt(SAVED_SHUFFLE_MODE, 0);
+ repeatMode = PreferenceManager.getDefaultSharedPreferences(this).getInt(SAVED_REPEAT_MODE, 0);
+ handleAndSendChangeInternal(SHUFFLE_MODE_CHANGED);
+ handleAndSendChangeInternal(REPEAT_MODE_CHANGED);
+
+ playerHandler.removeMessages(RESTORE_QUEUES);
+ playerHandler.sendEmptyMessage(RESTORE_QUEUES);
+ }
+
+ private synchronized void restoreQueuesAndPositionIfNecessary() {
+ if (!queuesRestored && playingQueue.isEmpty()) {
+ ArrayList restoredQueue = MusicPlaybackQueueStore.getInstance(this).getSavedPlayingQueue()
+ .blockingFirst();
+
+ ArrayList restoredOriginalQueue = MusicPlaybackQueueStore.getInstance(this).getSavedOriginalPlayingQueue()
+ .blockingFirst();
+
+ int restoredPosition = PreferenceManager.getDefaultSharedPreferences(this).getInt(SAVED_POSITION, -1);
+ int restoredPositionInTrack = PreferenceManager.getDefaultSharedPreferences(this).getInt(SAVED_POSITION_IN_TRACK, -1);
+
+ if (restoredQueue.size() > 0 && restoredQueue.size() == restoredOriginalQueue.size() && restoredPosition != -1) {
+ this.originalPlayingQueue = restoredOriginalQueue;
+ this.playingQueue = restoredQueue;
+
+ position = restoredPosition;
+ openCurrent();
+ prepareNext();
+
+ if (restoredPositionInTrack > 0) seek(restoredPositionInTrack);
+
+ notHandledMetaChangedForCurrentTrack = true;
+ sendChangeInternal(META_CHANGED);
+ sendChangeInternal(QUEUE_CHANGED);
+ }
+ }
+ queuesRestored = true;
+ }
+
+ private int quit() {
+ pause();
+ playingNotification.stop();
+
+ if (isServiceBound) {
+ return START_STICKY;
+ } else {
+ closeAudioEffectSession();
+ getAudioManager().abandonAudioFocus(audioFocusListener);
+ stopSelf();
+ return START_NOT_STICKY;
+ }
+ }
+
+ private void releaseResources() {
+ playerHandler.removeCallbacksAndMessages(null);
+ musicPlayerHandlerThread.quitSafely();
+ queueSaveHandler.removeCallbacksAndMessages(null);
+ queueSaveHandlerThread.quitSafely();
+ playback.release();
+ playback = null;
+ mediaSession.release();
+ }
+
+ public boolean isPlaying() {
+ return playback != null && playback.isPlaying();
+ }
+
+ public int getPosition() {
+ return position;
+ }
+
+ public void setPosition(final int position) {
+ // handle this on the handlers thread to avoid blocking the ui thread
+ playerHandler.removeMessages(SET_POSITION);
+ playerHandler.obtainMessage(SET_POSITION, position, 0).sendToTarget();
+ }
+
+ public void playNextSong(boolean force) {
+ playSongAt(getNextPosition(force));
+ }
+
+ private boolean openTrackAndPrepareNextAt(int position) {
+ synchronized (this) {
+ this.position = position;
+ boolean prepared = openCurrent();
+ if (prepared) prepareNextImpl();
+ notifyChange(META_CHANGED);
+ notHandledMetaChangedForCurrentTrack = false;
+ return prepared;
+ }
+ }
+
+ private boolean openCurrent() {
+ synchronized (this) {
+ try {
+ return playback.setDataSource(getTrackUri(getCurrentSong()));
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ }
+
+ private void prepareNext() {
+ playerHandler.removeMessages(PREPARE_NEXT);
+ playerHandler.obtainMessage(PREPARE_NEXT).sendToTarget();
+ }
+
+ private boolean prepareNextImpl() {
+ synchronized (this) {
+ try {
+ int nextPosition = getNextPosition(false);
+ playback.setNextDataSource(getTrackUri(getSongAt(nextPosition)));
+ this.nextPosition = nextPosition;
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+ }
+
+ private void closeAudioEffectSession() {
+ final Intent audioEffectsIntent = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION);
+ audioEffectsIntent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, playback.getAudioSessionId());
+ audioEffectsIntent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, getPackageName());
+ sendBroadcast(audioEffectsIntent);
+ }
+
+ private boolean requestFocus() {
+ return (getAudioManager().requestAudioFocus(audioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED);
+ }
+
+ public void initNotification() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && !PreferenceUtil.getInstance().classicNotification()) {
+ playingNotification = new PlayingNotificationImpl24();
+ } else {
+ playingNotification = new PlayingNotificationOreo();
+ }
+ playingNotification.init(this);
+ }
+
+ public void updateNotification() {
+ if (playingNotification != null && getCurrentSong().getId() != -1) {
+ playingNotification.update();
+ }
+ }
+
+ private void updateMediaSessionPlaybackState() {
+ mediaSession.setPlaybackState(
+ new PlaybackStateCompat.Builder()
+ .setActions(MEDIA_SESSION_ACTIONS)
+ .setState(isPlaying() ? PlaybackStateCompat.STATE_PLAYING : PlaybackStateCompat.STATE_PAUSED,
+ getPosition(), 1)
+ .build());
+ }
+
+ private void updateMediaSessionMetaData() {
+ final Song song = getCurrentSong();
+
+ if (song.getId() == -1) {
+ mediaSession.setMetadata(null);
+ return;
+ }
+
+ final MediaMetadataCompat.Builder metaData = new MediaMetadataCompat.Builder()
+ .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, song.getArtistName())
+ .putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, song.getArtistName())
+ .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, song.getAlbumName())
+ .putString(MediaMetadataCompat.METADATA_KEY_TITLE, song.getTitle())
+ .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, song.getDuration())
+ .putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, getPosition() + 1)
+ .putLong(MediaMetadataCompat.METADATA_KEY_YEAR, song.getYear())
+ .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, null);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ metaData.putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, getPlayingQueue().size());
+ }
+
+ if (PreferenceUtil.getInstance().albumArtOnLockscreen()) {
+ final Point screenSize = RetroUtil.getScreenSize(MusicService.this);
+ final BitmapRequestBuilder, Bitmap> request = SongGlideRequest.Builder.from(Glide.with(MusicService.this), song)
+ .checkIgnoreMediaStore(MusicService.this)
+ .asBitmap().build();
+ if (PreferenceUtil.getInstance().blurredAlbumArt()) {
+ request.transform(new BlurTransformation.Builder(MusicService.this).build());
+ }
+ runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ request.into(new SimpleTarget(screenSize.x, screenSize.y) {
+ @Override
+ public void onLoadFailed(Exception e, Drawable errorDrawable) {
+ super.onLoadFailed(e, errorDrawable);
+ mediaSession.setMetadata(metaData.build());
+ }
+
+ @Override
+ public void onResourceReady(Bitmap resource, GlideAnimation super Bitmap> glideAnimation) {
+ metaData.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, copy(resource));
+ mediaSession.setMetadata(metaData.build());
+ }
+ });
+ }
+ });
+ } else {
+ mediaSession.setMetadata(metaData.build());
+ }
+ }
+
+ public void runOnUiThread(Runnable runnable) {
+ uiThreadHandler.post(runnable);
+ }
+
+ public Song getCurrentSong() {
+ return getSongAt(getPosition());
+ }
+
+ public Song getSongAt(int position) {
+ if (position >= 0 && position < getPlayingQueue().size()) {
+ return getPlayingQueue().get(position);
+ } else {
+ return Song.Companion.getEmptySong();
+ }
+ }
+
+ public int getNextPosition(boolean force) {
+ int position = getPosition() + 1;
+ switch (getRepeatMode()) {
+ case REPEAT_MODE_ALL:
+ if (isLastTrack()) {
+ position = 0;
+ }
+ break;
+ case REPEAT_MODE_THIS:
+ if (force) {
+ if (isLastTrack()) {
+ position = 0;
+ }
+ } else {
+ position -= 1;
+ }
+ break;
+ default:
+ case REPEAT_MODE_NONE:
+ if (isLastTrack()) {
+ position -= 1;
+ }
+ break;
+ }
+ return position;
+ }
+
+ private boolean isLastTrack() {
+ return getPosition() == getPlayingQueue().size() - 1;
+ }
+
+ public ArrayList getPlayingQueue() {
+ return playingQueue;
+ }
+
+ public int getRepeatMode() {
+ return repeatMode;
+ }
+
+ public void setRepeatMode(final int repeatMode) {
+ switch (repeatMode) {
+ case REPEAT_MODE_NONE:
+ case REPEAT_MODE_ALL:
+ case REPEAT_MODE_THIS:
+ this.repeatMode = repeatMode;
+ PreferenceManager.getDefaultSharedPreferences(this).edit()
+ .putInt(SAVED_REPEAT_MODE, repeatMode)
+ .apply();
+ prepareNext();
+ handleAndSendChangeInternal(REPEAT_MODE_CHANGED);
+ break;
+ }
+ }
+
+ public void openQueue(@Nullable final ArrayList playingQueue, final int startPosition, final boolean startPlaying) {
+ if (playingQueue != null && !playingQueue.isEmpty() && startPosition >= 0 && startPosition < playingQueue.size()) {
+ // it is important to copy the playing queue here first as we might add/remove songs later
+ originalPlayingQueue = new ArrayList<>(playingQueue);
+ this.playingQueue = new ArrayList<>(originalPlayingQueue);
+
+ int position = startPosition;
+ if (shuffleMode == SHUFFLE_MODE_SHUFFLE) {
+ ShuffleHelper.INSTANCE.makeShuffleList(this.playingQueue, startPosition);
+ position = 0;
+ }
+ if (startPlaying) {
+ playSongAt(position);
+ } else {
+ setPosition(position);
+ }
+ notifyChange(QUEUE_CHANGED);
+ }
+ }
+
+ public void addSong(int position, Song song) {
+ playingQueue.add(position, song);
+ originalPlayingQueue.add(position, song);
+ notifyChange(QUEUE_CHANGED);
+ }
+
+ public void addSong(Song song) {
+ playingQueue.add(song);
+ originalPlayingQueue.add(song);
+ notifyChange(QUEUE_CHANGED);
+ }
+
+ public void addSongs(int position, List songs) {
+ playingQueue.addAll(position, songs);
+ originalPlayingQueue.addAll(position, songs);
+ notifyChange(QUEUE_CHANGED);
+ }
+
+ public void addSongs(List songs) {
+ playingQueue.addAll(songs);
+ originalPlayingQueue.addAll(songs);
+ notifyChange(QUEUE_CHANGED);
+ }
+
+ public void removeSong(int position) {
+ if (getShuffleMode() == SHUFFLE_MODE_NONE) {
+ playingQueue.remove(position);
+ originalPlayingQueue.remove(position);
+ } else {
+ originalPlayingQueue.remove(playingQueue.remove(position));
+ }
+
+ rePosition(position);
+
+ notifyChange(QUEUE_CHANGED);
+ }
+
+ public void removeSong(@NonNull Song song) {
+ for (int i = 0; i < playingQueue.size(); i++) {
+ if (playingQueue.get(i).getId() == song.getId()) {
+ playingQueue.remove(i);
+ rePosition(i);
+ }
+ }
+ for (int i = 0; i < originalPlayingQueue.size(); i++) {
+ if (originalPlayingQueue.get(i).getId() == song.getId()) {
+ originalPlayingQueue.remove(i);
+ }
+ }
+ notifyChange(QUEUE_CHANGED);
+ }
+
+ private void rePosition(int deletedPosition) {
+ int currentPosition = getPosition();
+ if (deletedPosition < currentPosition) {
+ position = currentPosition - 1;
+ } else if (deletedPosition == currentPosition) {
+ if (playingQueue.size() > deletedPosition) {
+ setPosition(position);
+ } else {
+ setPosition(position - 1);
+ }
+ }
+ }
+
+ public void moveSong(int from, int to) {
+ if (from == to) return;
+ final int currentPosition = getPosition();
+ Song songToMove = playingQueue.remove(from);
+ playingQueue.add(to, songToMove);
+ if (getShuffleMode() == SHUFFLE_MODE_NONE) {
+ Song tmpSong = originalPlayingQueue.remove(from);
+ originalPlayingQueue.add(to, tmpSong);
+ }
+ if (from > currentPosition && to <= currentPosition) {
+ position = currentPosition + 1;
+ } else if (from < currentPosition && to >= currentPosition) {
+ position = currentPosition - 1;
+ } else if (from == currentPosition) {
+ position = to;
+ }
+ notifyChange(QUEUE_CHANGED);
+ }
+
+ public void clearQueue() {
+ playingQueue.clear();
+ originalPlayingQueue.clear();
+
+ setPosition(-1);
+ notifyChange(QUEUE_CHANGED);
+ }
+
+ public void playSongAt(final int position) {
+ // handle this on the handlers thread to avoid blocking the ui thread
+ playerHandler.removeMessages(PLAY_SONG);
+ playerHandler.obtainMessage(PLAY_SONG, position, 0).sendToTarget();
+ }
+
+ private void playSongAtImpl(int position) {
+ if (openTrackAndPrepareNextAt(position)) {
+ play();
+ } else {
+ Toast.makeText(this, getResources().getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ public void pause() {
+ pausedByTransientLossOfFocus = false;
+ if (playback.isPlaying()) {
+ playback.pause();
+ notifyChange(PLAY_STATE_CHANGED);
+ }
+ }
+
+ public void play() {
+ synchronized (this) {
+ if (requestFocus()) {
+ if (!playback.isPlaying()) {
+ if (!playback.isInitialized()) {
+ playSongAt(getPosition());
+ } else {
+ playback.start();
+ if (!becomingNoisyReceiverRegistered) {
+ registerReceiver(becomingNoisyReceiver, becomingNoisyReceiverIntentFilter);
+ becomingNoisyReceiverRegistered = true;
+ }
+ if (notHandledMetaChangedForCurrentTrack) {
+ handleChangeInternal(META_CHANGED);
+ notHandledMetaChangedForCurrentTrack = false;
+ }
+ notifyChange(PLAY_STATE_CHANGED);
+
+ // fixes a bug where the volume would stay ducked because the AudioManager.AUDIOFOCUS_GAIN event is not sent
+ playerHandler.removeMessages(DUCK);
+ playerHandler.sendEmptyMessage(UNDUCK);
+ }
+ }
+ } else {
+ Toast.makeText(this, getResources().getString(R.string.audio_focus_denied), Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+
+ public void playSongs(ArrayList songs, int shuffleMode) {
+ if (songs != null && !songs.isEmpty()) {
+ if (shuffleMode == SHUFFLE_MODE_SHUFFLE) {
+ int startPosition = 0;
+ if (!songs.isEmpty()) {
+ startPosition = new Random().nextInt(songs.size());
+ }
+ openQueue(songs, startPosition, false);
+ setShuffleMode(shuffleMode);
+ } else {
+ openQueue(songs, 0, false);
+ }
+ play();
+ } else {
+ Toast.makeText(getApplicationContext(), R.string.playlist_is_empty, Toast.LENGTH_LONG).show();
+ }
+ }
+
+ public void playPreviousSong(boolean force) {
+ playSongAt(getPreviousPosition(force));
+ }
+
+ public void back(boolean force) {
+ if (getSongProgressMillis() > 2000) {
+ seek(0);
+ } else {
+ playPreviousSong(force);
+ }
+ }
+
+ public int getPreviousPosition(boolean force) {
+ int newPosition = getPosition() - 1;
+ switch (repeatMode) {
+ case REPEAT_MODE_ALL:
+ if (newPosition < 0) {
+ newPosition = getPlayingQueue().size() - 1;
+ }
+ break;
+ case REPEAT_MODE_THIS:
+ if (force) {
+ if (newPosition < 0) {
+ newPosition = getPlayingQueue().size() - 1;
+ }
+ } else {
+ newPosition = getPosition();
+ }
+ break;
+ default:
+ case REPEAT_MODE_NONE:
+ if (newPosition < 0) {
+ newPosition = 0;
+ }
+ break;
+ }
+ return newPosition;
+ }
+
+ public int getSongProgressMillis() {
+ return playback.position();
+ }
+
+ public int getSongDurationMillis() {
+ return playback.duration();
+ }
+
+ public long getQueueDurationMillis(int position) {
+ long duration = 0;
+ for (int i = position + 1; i < playingQueue.size(); i++)
+ duration += playingQueue.get(i).getDuration();
+ return duration;
+ }
+
+ public int seek(int millis) {
+ synchronized (this) {
+ try {
+ int newPosition = playback.seek(millis);
+ throttledSeekHandler.notifySeek();
+ return newPosition;
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+ }
+
+ public void cycleRepeatMode() {
+ switch (getRepeatMode()) {
+ case REPEAT_MODE_NONE:
+ setRepeatMode(REPEAT_MODE_ALL);
+ break;
+ case REPEAT_MODE_ALL:
+ setRepeatMode(REPEAT_MODE_THIS);
+ break;
+ default:
+ setRepeatMode(REPEAT_MODE_NONE);
+ break;
+ }
+ }
+
+ public void toggleShuffle() {
+ if (getShuffleMode() == SHUFFLE_MODE_NONE) {
+ setShuffleMode(SHUFFLE_MODE_SHUFFLE);
+ } else {
+ setShuffleMode(SHUFFLE_MODE_NONE);
+ }
+ }
+
+ public int getShuffleMode() {
+ return shuffleMode;
+ }
+
+ public void setShuffleMode(final int shuffleMode) {
+ PreferenceManager.getDefaultSharedPreferences(this).edit()
+ .putInt(SAVED_SHUFFLE_MODE, shuffleMode)
+ .apply();
+ switch (shuffleMode) {
+ case SHUFFLE_MODE_SHUFFLE:
+ this.shuffleMode = shuffleMode;
+ ShuffleHelper.INSTANCE.makeShuffleList(this.getPlayingQueue(), getPosition());
+ position = 0;
+ break;
+ case SHUFFLE_MODE_NONE:
+ this.shuffleMode = shuffleMode;
+ int currentSongId = getCurrentSong().getId();
+ playingQueue = new ArrayList<>(originalPlayingQueue);
+ int newPosition = 0;
+ for (Song song : getPlayingQueue()) {
+ if (song.getId() == currentSongId) {
+ newPosition = getPlayingQueue().indexOf(song);
+ }
+ }
+ position = newPosition;
+ break;
+ }
+ handleAndSendChangeInternal(SHUFFLE_MODE_CHANGED);
+ notifyChange(QUEUE_CHANGED);
+ }
+
+ private void notifyChange(@NonNull final String what) {
+ handleAndSendChangeInternal(what);
+ sendPublicIntent(what);
+ }
+
+ private void handleAndSendChangeInternal(@NonNull final String what) {
+ handleChangeInternal(what);
+ sendChangeInternal(what);
+ }
+
+ // to let other apps know whats playing. i.E. last.fm (scrobbling) or musixmatch
+ private void sendPublicIntent(@NonNull final String what) {
+ final Intent intent = new Intent(what.replace(RETRO_MUSIC_PACKAGE_NAME, MUSIC_PACKAGE_NAME));
+
+ final Song song = getCurrentSong();
+
+ intent.putExtra("id", song.getId());
+ intent.putExtra("artist", song.getArtistName());
+ intent.putExtra("album", song.getAlbumName());
+ intent.putExtra("track", song.getTitle());
+ intent.putExtra("duration", song.getDuration());
+ intent.putExtra("position", (long) getSongProgressMillis());
+ intent.putExtra("playing", isPlaying());
+ intent.putExtra("scrobbling_source", RETRO_MUSIC_PACKAGE_NAME);
+
+ sendStickyBroadcast(intent);
+
+ }
+
+ private void sendChangeInternal(final String what) {
+ sendBroadcast(new Intent(what));
+
+ }
+
+ private void handleChangeInternal(@NonNull final String what) {
+ switch (what) {
+ case PLAY_STATE_CHANGED:
+ updateNotification();
+ updateMediaSessionPlaybackState();
+ final boolean isPlaying = isPlaying();
+ if (!isPlaying && getSongProgressMillis() > 0) {
+ savePositionInTrack();
+ }
+ songPlayCountHelper.notifyPlayStateChanged(isPlaying);
+ break;
+ case META_CHANGED:
+ updateNotification();
+ updateMediaSessionMetaData();
+ savePosition();
+ savePositionInTrack();
+ final Song currentSong = getCurrentSong();
+ HistoryStore.getInstance(this).addSongId(currentSong.getId());
+ if (songPlayCountHelper.shouldBumpPlayCount()) {
+ SongPlayCountStore.getInstance(this).bumpPlayCount(songPlayCountHelper.getSong().getId());
+ }
+ songPlayCountHelper.notifySongChanged(currentSong);
+ break;
+ case QUEUE_CHANGED:
+ updateMediaSessionMetaData(); // because playing queue size might have changed
+ saveState();
+ if (playingQueue.size() > 0) {
+ prepareNext();
+ } else {
+ playingNotification.stop();
+ }
+ break;
+ }
+ }
+
+ public int getAudioSessionId() {
+ return playback.getAudioSessionId();
+ }
+
+ public MediaSessionCompat getMediaSession() {
+ return mediaSession;
+ }
+
+ public void releaseWakeLock() {
+ if (wakeLock.isHeld()) {
+ wakeLock.release();
+ }
+ }
+
+ public void acquireWakeLock(long milli) {
+ wakeLock.acquire(milli);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ switch (key) {
+ case PreferenceUtil.GAPLESS_PLAYBACK:
+ if (sharedPreferences.getBoolean(key, false)) {
+ prepareNext();
+ } else {
+ playback.setNextDataSource(null);
+ }
+ break;
+ case PreferenceUtil.ALBUM_ART_ON_LOCKSCREEN:
+ case PreferenceUtil.BLURRED_ALBUM_ART:
+ updateMediaSessionMetaData();
+ break;
+ case PreferenceUtil.COLORED_NOTIFICATION:
+ case PreferenceUtil.DOMINANT_COLOR:
+ updateNotification();
+ break;
+ case PreferenceUtil.CLASSIC_NOTIFICATION:
+ initNotification();
+ updateNotification();
+ break;
+ case PreferenceUtil.TOGGLE_HEADSET:
+ registerHeadsetEvents();
+ break;
+ }
+ }
+
+ private void registerHeadsetEvents() {
+ if (!headsetReceiverRegistered && PreferenceUtil.getInstance().getHeadsetPlugged()) {
+ registerReceiver(headsetReceiver, headsetReceiverIntentFilter);
+ headsetReceiverRegistered = true;
+ }
+ }
+
+ @Override
+ public void onTrackWentToNext() {
+ playerHandler.sendEmptyMessage(TRACK_WENT_TO_NEXT);
+ }
+
+ @Override
+ public void onTrackEnded() {
+ acquireWakeLock(30000);
+ playerHandler.sendEmptyMessage(TRACK_ENDED);
+ }
+
+
+ private static final class QueueSaveHandler extends Handler {
+ @NonNull
+ private final WeakReference mService;
+
+ QueueSaveHandler(final MusicService service, @NonNull final Looper looper) {
+ super(looper);
+ mService = new WeakReference<>(service);
+ }
+
+ @Override
+ public void handleMessage(@NonNull Message msg) {
+ final MusicService service = mService.get();
+ switch (msg.what) {
+ case SAVE_QUEUES:
+ service.saveQueuesImpl();
+ break;
+ }
+ }
+ }
+
+ private static final class PlaybackHandler extends Handler {
+ @NonNull
+ private final WeakReference mService;
+ private float currentDuckVolume = 1.0f;
+
+ PlaybackHandler(final MusicService service, @NonNull final Looper looper) {
+ super(looper);
+ mService = new WeakReference<>(service);
+ }
+
+ @Override
+ public void handleMessage(@NonNull final Message msg) {
+ final MusicService service = mService.get();
+ if (service == null) {
+ return;
+ }
+
+ switch (msg.what) {
+ case DUCK:
+ if (PreferenceUtil.getInstance().audioDucking()) {
+ currentDuckVolume -= .05f;
+ if (currentDuckVolume > .2f) {
+ sendEmptyMessageDelayed(DUCK, 10);
+ } else {
+ currentDuckVolume = .2f;
+ }
+ } else {
+ currentDuckVolume = 1f;
+ }
+ service.playback.setVolume(currentDuckVolume);
+ break;
+
+ case UNDUCK:
+ if (PreferenceUtil.getInstance().audioDucking()) {
+ currentDuckVolume += .03f;
+ if (currentDuckVolume < 1f) {
+ sendEmptyMessageDelayed(UNDUCK, 10);
+ } else {
+ currentDuckVolume = 1f;
+ }
+ } else {
+ currentDuckVolume = 1f;
+ }
+ service.playback.setVolume(currentDuckVolume);
+ break;
+
+ case TRACK_WENT_TO_NEXT:
+ if (service.getRepeatMode() == REPEAT_MODE_NONE && service.isLastTrack()) {
+ service.pause();
+ service.seek(0);
+ } else {
+ service.position = service.nextPosition;
+ service.prepareNextImpl();
+ service.notifyChange(META_CHANGED);
+ }
+ break;
+
+ case TRACK_ENDED:
+ if (service.getRepeatMode() == REPEAT_MODE_NONE && service.isLastTrack()) {
+ service.notifyChange(PLAY_STATE_CHANGED);
+ service.seek(0);
+ } else {
+ service.playNextSong(false);
+ }
+ sendEmptyMessage(RELEASE_WAKELOCK);
+ break;
+
+ case RELEASE_WAKELOCK:
+ service.releaseWakeLock();
+ break;
+
+ case PLAY_SONG:
+ service.playSongAtImpl(msg.arg1);
+ break;
+
+ case SET_POSITION:
+ service.openTrackAndPrepareNextAt(msg.arg1);
+ service.notifyChange(PLAY_STATE_CHANGED);
+ break;
+
+ case PREPARE_NEXT:
+ service.prepareNextImpl();
+ break;
+
+ case RESTORE_QUEUES:
+ service.restoreQueuesAndPositionIfNecessary();
+ break;
+
+ case FOCUS_CHANGE:
+ switch (msg.arg1) {
+ case AudioManager.AUDIOFOCUS_GAIN:
+ if (!service.isPlaying() && service.pausedByTransientLossOfFocus) {
+ service.play();
+ service.pausedByTransientLossOfFocus = false;
+ }
+ removeMessages(DUCK);
+ sendEmptyMessage(UNDUCK);
+ break;
+
+ case AudioManager.AUDIOFOCUS_LOSS:
+ // Lost focus for an unbounded amount of time: stop playback and release media playback
+ service.pause();
+ break;
+
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+ // Lost focus for a short time, but we have to stop
+ // playback. We don't release the media playback because playback
+ // is likely to resume
+ boolean wasPlaying = service.isPlaying();
+ service.pause();
+ service.pausedByTransientLossOfFocus = wasPlaying;
+ break;
+
+ case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+ // Lost focus for a short time, but it's ok to keep playing
+ // at an attenuated level
+ removeMessages(UNDUCK);
+ sendEmptyMessage(DUCK);
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ private static class SongPlayCountHelper {
+ public static final String TAG = SongPlayCountHelper.class.getSimpleName();
+
+ private StopWatch stopWatch = new StopWatch();
+ private Song song = Song.Companion.getEmptySong();
+
+ public Song getSong() {
+ return song;
+ }
+
+ boolean shouldBumpPlayCount() {
+ return song.getDuration() * 0.5d < stopWatch.getElapsedTime();
+ }
+
+ void notifySongChanged(Song song) {
+ synchronized (this) {
+ stopWatch.reset();
+ this.song = song;
+ }
+ }
+
+ void notifyPlayStateChanged(boolean isPlaying) {
+ synchronized (this) {
+ if (isPlaying) {
+ stopWatch.start();
+ } else {
+ stopWatch.pause();
+ }
+ }
+ }
+ }
+
+ public class MusicBinder extends Binder {
+ @NonNull
+ public MusicService getService() {
+ return MusicService.this;
+ }
+ }
+
+ private class MediaStoreObserver extends ContentObserver implements Runnable {
+ // milliseconds to delay before calling refresh to aggregate events
+ private static final long REFRESH_DELAY = 500;
+ private Handler mHandler;
+
+ MediaStoreObserver(Handler handler) {
+ super(handler);
+ mHandler = handler;
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ // if a change is detected, remove any scheduled callback
+ // then post a new one. This is intended to prevent closely
+ // spaced events from generating multiple refresh calls
+ mHandler.removeCallbacks(this);
+ mHandler.postDelayed(this, REFRESH_DELAY);
+ }
+
+ @Override
+ public void run() {
+ // actually call refresh when the delayed callback fires
+ // do not send a sticky broadcast here
+ handleAndSendChangeInternal(MEDIA_STORE_CHANGED);
+ }
+ }
+
+ private class ThrottledSeekHandler implements Runnable {
+ // milliseconds to throttle before calling run() to aggregate events
+ private static final long THROTTLE = 500;
+ private Handler mHandler;
+
+ ThrottledSeekHandler(Handler handler) {
+ mHandler = handler;
+ }
+
+ void notifySeek() {
+ mHandler.removeCallbacks(this);
+ mHandler.postDelayed(this, THROTTLE);
+ }
+
+ @Override
+ public void run() {
+ savePositionInTrack();
+ sendPublicIntent(PLAY_STATE_CHANGED); // for musixmatch synced lyrics
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt b/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt
deleted file mode 100644
index 813385cf..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/service/MusicService.kt
+++ /dev/null
@@ -1,1247 +0,0 @@
-package code.name.monkey.retromusic.service
-
-import android.annotation.SuppressLint
-import android.app.PendingIntent
-import android.app.Service
-import android.content.*
-import android.database.ContentObserver
-import android.graphics.Bitmap
-import android.graphics.drawable.Drawable
-import android.media.AudioManager
-import android.media.audiofx.AudioEffect
-import android.media.session.MediaSession
-import android.os.*
-import android.preference.PreferenceManager
-import android.provider.MediaStore
-import android.support.v4.media.MediaMetadataCompat
-import android.support.v4.media.session.MediaSessionCompat
-import android.support.v4.media.session.PlaybackStateCompat
-import android.telephony.PhoneStateListener
-import android.telephony.TelephonyManager
-import android.util.Log
-import android.widget.Toast
-import code.name.monkey.retromusic.Constants.ACTION_PAUSE
-import code.name.monkey.retromusic.Constants.ACTION_PLAY
-import code.name.monkey.retromusic.Constants.ACTION_PLAY_PLAYLIST
-import code.name.monkey.retromusic.Constants.ACTION_QUIT
-import code.name.monkey.retromusic.Constants.ACTION_SKIP
-import code.name.monkey.retromusic.Constants.ACTION_STOP
-import code.name.monkey.retromusic.Constants.ACTION_TOGGLE_PAUSE
-import code.name.monkey.retromusic.Constants.APP_WIDGET_UPDATE
-import code.name.monkey.retromusic.Constants.EXTRA_APP_WIDGET_NAME
-import code.name.monkey.retromusic.Constants.INTENT_EXTRA_PLAYLIST
-import code.name.monkey.retromusic.Constants.INTENT_EXTRA_SHUFFLE_MODE
-import code.name.monkey.retromusic.Constants.MEDIA_STORE_CHANGED
-import code.name.monkey.retromusic.Constants.META_CHANGED
-import code.name.monkey.retromusic.Constants.MUSIC_PACKAGE_NAME
-import code.name.monkey.retromusic.Constants.PLAY_STATE_CHANGED
-import code.name.monkey.retromusic.Constants.QUEUE_CHANGED
-import code.name.monkey.retromusic.Constants.REPEAT_MODE_CHANGED
-import code.name.monkey.retromusic.Constants.RETRO_MUSIC_PACKAGE_NAME
-import code.name.monkey.retromusic.Constants.SHUFFLE_MODE_CHANGED
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.glide.BlurTransformation
-import code.name.monkey.retromusic.glide.SongGlideRequest
-import code.name.monkey.retromusic.helper.MusicPlayerRemote.setShuffleMode
-import code.name.monkey.retromusic.helper.ShuffleHelper
-import code.name.monkey.retromusic.helper.StopWatch
-import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
-import code.name.monkey.retromusic.model.AbsCustomPlaylist
-import code.name.monkey.retromusic.model.Playlist
-import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.providers.HistoryStore
-import code.name.monkey.retromusic.providers.MusicPlaybackQueueStore
-import code.name.monkey.retromusic.providers.SongPlayCountStore
-import code.name.monkey.retromusic.service.notification.PlayingNotification
-import code.name.monkey.retromusic.service.notification.PlayingNotificationImpl24
-import code.name.monkey.retromusic.service.notification.PlayingNotificationOreo
-import code.name.monkey.retromusic.service.playback.Playback
-import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.util.RetroUtil
-import com.bumptech.glide.Glide
-import com.bumptech.glide.request.animation.GlideAnimation
-import com.bumptech.glide.request.target.SimpleTarget
-import com.google.android.gms.cast.framework.media.MediaIntentReceiver.ACTION_REWIND
-import java.lang.ref.WeakReference
-import java.util.*
-
-/**
- * @author Karim Abou Zeid (kabouzeid), Andrew Neal
- */
-class MusicService : Service(), SharedPreferences.OnSharedPreferenceChangeListener, Playback.PlaybackCallbacks {
- private val musicBind = MusicBinder()
- private var playback: Playback? = null
- var playingQueue = ArrayList()
- private set
- private var originalPlayingQueue = ArrayList()
- var position = -1
- set(value) {
- playerHandler!!.removeMessages(SET_POSITION)
- playerHandler!!.obtainMessage(SET_POSITION, value, 0).sendToTarget()
- }
- private var nextPosition = -1
- var shuffleMode: Int = 0
- set(value) {
- PreferenceManager.getDefaultSharedPreferences(this).edit()
- .putInt(SAVED_SHUFFLE_MODE, value)
- .apply()
- when (value) {
- SHUFFLE_MODE_SHUFFLE -> {
- field = value
- ShuffleHelper.makeShuffleList(this.playingQueue, position)
- position = 0
- }
- SHUFFLE_MODE_NONE -> {
- field = value
- val currentSongId = currentSong.id
- playingQueue = ArrayList(originalPlayingQueue)
- var newPosition = 0
- for (song in playingQueue) {
- if (song.id == currentSongId) {
- newPosition = playingQueue.indexOf(song)
- }
- }
- position = newPosition
- }
- }
- handleAndSendChangeInternal(SHUFFLE_MODE_CHANGED)
- notifyChange(QUEUE_CHANGED)
- }
- var repeatMode: Int = 0
- set(value) {
- when (value) {
- REPEAT_MODE_NONE, REPEAT_MODE_ALL, REPEAT_MODE_THIS -> {
- field = value
- PreferenceManager.getDefaultSharedPreferences(this).edit()
- .putInt(SAVED_REPEAT_MODE, repeatMode)
- .apply()
- prepareNext()
- handleAndSendChangeInternal(REPEAT_MODE_CHANGED)
- }
- }
- }
- private var queuesRestored: Boolean = false
- private var pausedByTransientLossOfFocus: Boolean = false
- private val becomingNoisyReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- if (intent.action != null && intent.action == AudioManager.ACTION_AUDIO_BECOMING_NOISY) {
- pause()
- }
- }
- }
- private var playingNotification: PlayingNotification? = null
- private var audioManager: AudioManager? = null
- var mediaSession: MediaSessionCompat? = null
- private set
- private var wakeLock: PowerManager.WakeLock? = null
- private var playerHandler: PlaybackHandler? = null
- private val audioFocusListener = AudioManager.OnAudioFocusChangeListener { focusChange -> playerHandler!!.obtainMessage(FOCUS_CHANGE, focusChange, 0).sendToTarget() }
- private var queueSaveHandler: QueueSaveHandler? = null
- private var musicPlayerHandlerThread: HandlerThread? = null
- private var queueSaveHandlerThread: HandlerThread? = null
- private val songPlayCountHelper = SongPlayCountHelper()
- private var throttledSeekHandler: ThrottledSeekHandler? = null
- private var becomingNoisyReceiverRegistered: Boolean = false
- private val becomingNoisyReceiverIntentFilter = IntentFilter(AudioManager.ACTION_AUDIO_BECOMING_NOISY)
- private var mediaStoreObserver: ContentObserver? = null
- private var notHandledMetaChangedForCurrentTrack: Boolean = false
- private val phoneStateListener = object : PhoneStateListener() {
- override fun onCallStateChanged(state: Int, incomingNumber: String) {
- when (state) {
- TelephonyManager.CALL_STATE_IDLE ->
- //Not in call: Play music
- play()
- TelephonyManager.CALL_STATE_RINGING, TelephonyManager.CALL_STATE_OFFHOOK ->
- //A call is dialing, active or on hold
- pause()
- }
- super.onCallStateChanged(state, incomingNumber)
- }
- }
- private var isServiceBound: Boolean = false
- private var uiThreadHandler: Handler? = null
- private val widgetIntentReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val command = intent.getStringExtra(EXTRA_APP_WIDGET_NAME)
- }
- }
- private val headsetReceiverIntentFilter = IntentFilter(Intent.ACTION_HEADSET_PLUG)
- private var headsetReceiverRegistered = false
- private val headsetReceiver = object : BroadcastReceiver() {
- override fun onReceive(context: Context, intent: Intent) {
- val action = intent.action
- if (action != null) {
- when (action) {
- Intent.ACTION_HEADSET_PLUG -> {
- val state = intent.getIntExtra("state", -1)
- when (state) {
- 0 -> {
- Log.d(TAG, "Headset unplugged")
- pause()
- }
- 1 -> {
- Log.d(TAG, "Headset plugged")
- play()
- }
- }
- }
- }
- }
- }
- }
-
- val isPlaying: Boolean
- get() = playback != null && playback!!.isPlaying
-
- val currentSong: Song
- get() = getSongAt(position)
-
- private val isLastTrack: Boolean
- get() = position == playingQueue.size - 1
-
- val songProgressMillis: Int
- get() = playback!!.position()
-
- val songDurationMillis: Int
- get() = playback!!.duration()
-
- val audioSessionId: Int
- get() = playback!!.audioSessionId
-
-
- override fun onCreate() {
- super.onCreate()
-
- val telephonyManager = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
- telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
-
- val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
- wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, javaClass.name)
- wakeLock!!.setReferenceCounted(false)
-
- musicPlayerHandlerThread = HandlerThread("PlaybackHandler")
- musicPlayerHandlerThread!!.start()
- playerHandler = PlaybackHandler(this, musicPlayerHandlerThread!!.looper)
-
- playback = MultiPlayer(this)
- playback!!.setCallbacks(this)
-
- setupMediaSession()
-
- // queue saving needs to run on a separate thread so that it doesn't block the playback handler events
- queueSaveHandlerThread = HandlerThread("QueueSaveHandler", Process.THREAD_PRIORITY_BACKGROUND)
- queueSaveHandlerThread!!.start()
- queueSaveHandler = QueueSaveHandler(this, queueSaveHandlerThread!!.looper)
-
- uiThreadHandler = Handler()
-
- registerReceiver(widgetIntentReceiver, IntentFilter(APP_WIDGET_UPDATE))
-
- initNotification()
-
- mediaStoreObserver = MediaStoreObserver(playerHandler!!)
- throttledSeekHandler = ThrottledSeekHandler(playerHandler!!)
- contentResolver.registerContentObserver(
- MediaStore.Audio.Media.INTERNAL_CONTENT_URI, true, mediaStoreObserver!!)
- contentResolver.registerContentObserver(
- MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, true, mediaStoreObserver!!)
-
- PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this)
-
- restoreState()
-
- mediaSession!!.isActive = true
-
- sendBroadcast(Intent("code.name.monkey.retromusic.RETRO_MUSIC_SERVICE_CREATED"))
-
- registerHeadsetEvents()
-
-
- }
-
- private fun getAudioManager(): AudioManager? {
- if (audioManager == null) {
- audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
- }
- return audioManager
- }
-
- @SuppressLint("WrongConstant")
- private fun setupMediaSession() {
- val mediaButtonReceiverComponentName = ComponentName(applicationContext, MediaButtonIntentReceiver::class.java)
-
- val mediaButtonIntent = Intent(Intent.ACTION_MEDIA_BUTTON)
- mediaButtonIntent.component = mediaButtonReceiverComponentName
-
-
- val mediaButtonReceiverPendingIntent = PendingIntent.getBroadcast(applicationContext, 0, mediaButtonIntent, 0)
-
- mediaSession = MediaSessionCompat(this, "RetroMusicPlayer", mediaButtonReceiverComponentName, mediaButtonReceiverPendingIntent)
- mediaSession!!.setCallback(object : MediaSessionCompat.Callback() {
- override fun onPlay() {
- play()
- }
-
- override fun onPause() {
- pause()
- }
-
- override fun onSkipToNext() {
- playNextSong(true)
- }
-
- override fun onSkipToPrevious() {
- back(true)
- }
-
- override fun onStop() {
- quit()
- }
-
- override fun onSeekTo(pos: Long) {
- seek(pos.toInt())
- }
-
- override fun onMediaButtonEvent(mediaButtonEvent: Intent): Boolean {
- return MediaButtonIntentReceiver.handleIntent(this@MusicService, mediaButtonEvent)
- }
- })
-
- mediaSession!!.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS or MediaSession.FLAG_HANDLES_MEDIA_BUTTONS)
-
- mediaSession!!.setMediaButtonReceiver(mediaButtonReceiverPendingIntent)
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- if (intent != null) {
- if (intent.action != null) {
- restoreQueuesAndPositionIfNecessary()
- val action = intent.action
- when (action) {
- ACTION_TOGGLE_PAUSE -> if (isPlaying) {
- pause()
- } else {
- play()
- }
- ACTION_PAUSE -> pause()
- ACTION_PLAY -> play()
- ACTION_PLAY_PLAYLIST -> {
- val playlist = intent.getParcelableExtra(INTENT_EXTRA_PLAYLIST)
- val shuffleMode = intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, shuffleMode)
- if (playlist != null) {
- val playlistSongs: ArrayList
- if (playlist is AbsCustomPlaylist) {
- playlistSongs = playlist.getSongs(applicationContext).blockingFirst()
- } else {
-
- playlistSongs = PlaylistSongsLoader.getPlaylistSongList(applicationContext, playlist.id).blockingFirst()
- }
- if (!playlistSongs.isEmpty()) {
- if (shuffleMode == SHUFFLE_MODE_SHUFFLE) {
- val startPosition: Int = Random().nextInt(playlistSongs.size)
- openQueue(playlistSongs, startPosition, true)
- setShuffleMode(shuffleMode)
- } else {
- openQueue(playlistSongs, 0, true)
- }
- } else {
- Toast.makeText(applicationContext, R.string.playlist_is_empty, Toast.LENGTH_LONG).show()
- }
- } else {
- Toast.makeText(applicationContext, R.string.playlist_is_empty, Toast.LENGTH_LONG).show()
- }
- }
- ACTION_REWIND -> back(true)
- ACTION_SKIP -> playNextSong(true)
- ACTION_STOP, ACTION_QUIT -> return quit()
- }
- }
- }
-
- return Service.START_STICKY
- }
-
-
- override fun onDestroy() {
- unregisterReceiver(widgetIntentReceiver)
- if (becomingNoisyReceiverRegistered) {
- unregisterReceiver(becomingNoisyReceiver)
- becomingNoisyReceiverRegistered = false
- }
- if (headsetReceiverRegistered) {
- unregisterReceiver(headsetReceiver)
- headsetReceiverRegistered = false
- }
- mediaSession!!.isActive = false
- quit()
- releaseResources()
- contentResolver.unregisterContentObserver(mediaStoreObserver!!)
- PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this)
- wakeLock!!.release()
-
- sendBroadcast(Intent("code.name.monkey.retromusic.RETRO_MUSIC_MUSIC_SERVICE_DESTROYED"))
- }
-
- override fun onBind(intent: Intent): IBinder? {
- isServiceBound = true
- return musicBind
- }
-
- override fun onRebind(intent: Intent) {
- isServiceBound = true
- }
-
- override fun onUnbind(intent: Intent): Boolean {
- isServiceBound = false
- if (!isPlaying) {
- stopSelf()
- }
- return true
- }
-
- private fun saveQueuesImpl() {
- MusicPlaybackQueueStore.getInstance(this).saveQueues(playingQueue, originalPlayingQueue)
- }
-
- private fun savePosition() {
- PreferenceManager.getDefaultSharedPreferences(this).edit().putInt(SAVED_POSITION, position).apply()
- }
-
- private fun savePositionInTrack() {
- PreferenceManager.getDefaultSharedPreferences(this).edit().putInt(SAVED_POSITION_IN_TRACK, songProgressMillis).apply()
- }
-
- private fun saveState() {
- saveQueues()
- savePosition()
- savePositionInTrack()
- }
-
- private fun saveQueues() {
- queueSaveHandler!!.removeMessages(SAVE_QUEUES)
- queueSaveHandler!!.sendEmptyMessage(SAVE_QUEUES)
- }
-
- private fun restoreState() {
- shuffleMode = PreferenceManager.getDefaultSharedPreferences(this).getInt(SAVED_SHUFFLE_MODE, 0)
- repeatMode = PreferenceManager.getDefaultSharedPreferences(this).getInt(SAVED_REPEAT_MODE, 0)
- handleAndSendChangeInternal(SHUFFLE_MODE_CHANGED)
- handleAndSendChangeInternal(REPEAT_MODE_CHANGED)
-
- playerHandler!!.removeMessages(RESTORE_QUEUES)
- playerHandler!!.sendEmptyMessage(RESTORE_QUEUES)
- }
-
- @Synchronized
- private fun restoreQueuesAndPositionIfNecessary() {
- if (!queuesRestored && playingQueue.isEmpty()) {
- val restoredQueue = MusicPlaybackQueueStore.getInstance(this).savedPlayingQueue
- .blockingFirst()
-
- val restoredOriginalQueue = MusicPlaybackQueueStore.getInstance(this).savedOriginalPlayingQueue
- .blockingFirst()
-
- val restoredPosition = PreferenceManager.getDefaultSharedPreferences(this).getInt(SAVED_POSITION, -1)
- val restoredPositionInTrack = PreferenceManager.getDefaultSharedPreferences(this).getInt(SAVED_POSITION_IN_TRACK, -1)
-
- if (restoredQueue.size > 0 && restoredQueue.size == restoredOriginalQueue.size && restoredPosition != -1) {
- this.originalPlayingQueue = restoredOriginalQueue
- this.playingQueue = restoredQueue
-
- position = restoredPosition
- openCurrent()
- prepareNext()
-
- if (restoredPositionInTrack > 0) seek(restoredPositionInTrack)
-
- notHandledMetaChangedForCurrentTrack = true
- sendChangeInternal(META_CHANGED)
- sendChangeInternal(QUEUE_CHANGED)
- }
- }
- queuesRestored = true
- }
-
- @SuppressLint("WrongConstant")
- private fun quit(): Int {
- pause()
- playingNotification!!.stop()
-
- if (isServiceBound) {
- return Service.START_STICKY
- } else {
- closeAudioEffectSession()
- getAudioManager()!!.abandonAudioFocus(audioFocusListener)
- stopSelf()
- return Service.START_NOT_STICKY
- }
- }
-
- private fun releaseResources() {
- playerHandler!!.removeCallbacksAndMessages(null)
- musicPlayerHandlerThread!!.quitSafely()
- queueSaveHandler!!.removeCallbacksAndMessages(null)
- queueSaveHandlerThread!!.quitSafely()
- playback!!.release()
- playback = null
- mediaSession!!.release()
- }
-
- fun playNextSong(force: Boolean) {
- playSongAt(getNextPosition(force))
- }
-
- private fun openTrackAndPrepareNextAt(position: Int): Boolean {
- synchronized(this) {
- this.position = position
- val prepared = openCurrent()
- if (prepared) prepareNextImpl()
- notifyChange(META_CHANGED)
- notHandledMetaChangedForCurrentTrack = false
- return prepared
- }
- }
-
- private fun openCurrent(): Boolean {
- synchronized(this) {
- try {
- return playback!!.setDataSource(getTrackUri(currentSong))
- } catch (e: Exception) {
- return false
- }
-
- }
- }
-
- private fun prepareNext() {
- playerHandler!!.removeMessages(PREPARE_NEXT)
- playerHandler!!.obtainMessage(PREPARE_NEXT).sendToTarget()
- }
-
- private fun prepareNextImpl(): Boolean {
- synchronized(this) {
- return try {
- val nextPosition = getNextPosition(false)
- playback!!.setNextDataSource(getTrackUri(getSongAt(nextPosition)))
- this.nextPosition = nextPosition
- true
- } catch (e: Exception) {
- false
- }
-
- }
- }
-
- private fun closeAudioEffectSession() {
- val audioEffectsIntent = Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION)
- audioEffectsIntent.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, playback!!.audioSessionId)
- audioEffectsIntent.putExtra(AudioEffect.EXTRA_PACKAGE_NAME, packageName)
- sendBroadcast(audioEffectsIntent)
- }
-
- private fun requestFocus(): Boolean {
- return getAudioManager()!!.requestAudioFocus(audioFocusListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN) == AudioManager.AUDIOFOCUS_REQUEST_GRANTED
- }
-
- fun initNotification() {
- playingNotification = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && !PreferenceUtil.getInstance().classicNotification()) {
- PlayingNotificationImpl24()
- } else {
- PlayingNotificationOreo()
- }
- playingNotification!!.init(this)
- }
-
- fun updateNotification() {
- if (playingNotification != null && currentSong.id != -1) {
- playingNotification!!.update()
- }
- }
-
- private fun updateMediaSessionPlaybackState() {
- mediaSession!!.setPlaybackState(
- PlaybackStateCompat.Builder()
- .setActions(MEDIA_SESSION_ACTIONS)
- .setState(if (isPlaying) PlaybackStateCompat.STATE_PLAYING else PlaybackStateCompat.STATE_PAUSED,
- position.toLong(), 1f)
- .build())
- }
-
- private fun updateMediaSessionMetaData() {
- val song = currentSong
-
- if (song.id == -1) {
- mediaSession!!.setMetadata(null)
- return
- }
-
- val metaData = MediaMetadataCompat.Builder()
- .putString(MediaMetadataCompat.METADATA_KEY_ARTIST, song.artistName)
- .putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, song.artistName)
- .putString(MediaMetadataCompat.METADATA_KEY_ALBUM, song.albumName)
- .putString(MediaMetadataCompat.METADATA_KEY_TITLE, song.title)
- .putLong(MediaMetadataCompat.METADATA_KEY_DURATION, song.duration)
- .putLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER, (position + 1).toLong())
- .putLong(MediaMetadataCompat.METADATA_KEY_YEAR, song.year.toLong())
- .putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, null)
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- metaData.putLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS, playingQueue.size.toLong())
- }
-
- if (PreferenceUtil.getInstance().albumArtOnLockscreen()) {
- val screenSize = RetroUtil.getScreenSize(this@MusicService)
- val request = SongGlideRequest.Builder.from(Glide.with(this@MusicService), song)
- .checkIgnoreMediaStore(this@MusicService)
- .asBitmap().build()
- if (PreferenceUtil.getInstance().blurredAlbumArt()) {
- request.transform(BlurTransformation.Builder(this@MusicService).build())
- }
- runOnUiThread(Runnable {
- request.into(object : SimpleTarget(screenSize.x, screenSize.y) {
- override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
- super.onLoadFailed(e, errorDrawable)
- mediaSession!!.setMetadata(metaData.build())
- }
-
- override fun onResourceReady(resource: Bitmap, glideAnimation: GlideAnimation) {
- metaData.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, copy(resource))
- mediaSession!!.setMetadata(metaData.build())
- }
- })
- })
- } else {
- mediaSession!!.setMetadata(metaData.build())
- }
- }
-
- fun runOnUiThread(runnable: Runnable) {
- uiThreadHandler!!.post(runnable)
- }
-
- private fun getSongAt(position: Int): Song {
- return if (position >= 0 && position < playingQueue.size) {
- playingQueue[position]
- } else {
- Song.EMPTY_SONG
- }
- }
-
- private fun getNextPosition(force: Boolean): Int {
- var position = position + 1
- when (repeatMode) {
- REPEAT_MODE_ALL -> if (isLastTrack) {
- position = 0
- }
- REPEAT_MODE_THIS -> if (force) {
- if (isLastTrack) {
- position = 0
- }
- } else {
- position -= 1
- }
- REPEAT_MODE_NONE -> if (isLastTrack) {
- position -= 1
- }
- else -> if (isLastTrack) {
- position -= 1
- }
- }
- return position
- }
-
-
- fun openQueue(playingQueue: ArrayList?, startPosition: Int, startPlaying: Boolean) {
- if (playingQueue != null && !playingQueue.isEmpty() && startPosition >= 0 && startPosition < playingQueue.size) {
- // it is important to copy the playing queue here first as we might add/remove songs later
- originalPlayingQueue = ArrayList(playingQueue)
- this.playingQueue = ArrayList(originalPlayingQueue)
-
- var position = startPosition
- if (shuffleMode == SHUFFLE_MODE_SHUFFLE) {
- ShuffleHelper.makeShuffleList(this.playingQueue, startPosition)
- position = 0
- }
- if (startPlaying) {
- playSongAt(position)
- } else {
- this.position = position
- }
- notifyChange(QUEUE_CHANGED)
- }
- }
-
- fun addSong(position: Int, song: Song) {
- playingQueue.add(position, song)
- originalPlayingQueue.add(position, song)
- notifyChange(QUEUE_CHANGED)
- }
-
- fun addSong(song: Song) {
- playingQueue.add(song)
- originalPlayingQueue.add(song)
- notifyChange(QUEUE_CHANGED)
- }
-
- fun addSongs(position: Int, songs: List) {
- playingQueue.addAll(position, songs)
- originalPlayingQueue.addAll(position, songs)
- notifyChange(QUEUE_CHANGED)
- }
-
- fun addSongs(songs: List) {
- playingQueue.addAll(songs)
- originalPlayingQueue.addAll(songs)
- notifyChange(QUEUE_CHANGED)
- }
-
- fun removeSong(position: Int) {
- if (shuffleMode == SHUFFLE_MODE_NONE) {
- playingQueue.removeAt(position)
- originalPlayingQueue.removeAt(position)
- } else {
- originalPlayingQueue.remove(playingQueue.removeAt(position))
- }
-
- rePosition(position)
-
- notifyChange(QUEUE_CHANGED)
- }
-
- fun removeSong(song: Song) {
- for (i in playingQueue.indices) {
- if (playingQueue[i].id == song.id) {
- playingQueue.removeAt(i)
- rePosition(i)
- }
- }
- for (i in originalPlayingQueue.indices) {
- if (originalPlayingQueue[i].id == song.id) {
- originalPlayingQueue.removeAt(i)
- }
- }
- notifyChange(QUEUE_CHANGED)
- }
-
- private fun rePosition(deletedPosition: Int) {
- val currentPosition = position
- if (deletedPosition < currentPosition) {
- position = currentPosition - 1
- } else if (deletedPosition == currentPosition) {
- if (playingQueue.size > deletedPosition) {
- this.position = position
- } else {
- this.position = position - 1
- }
- }
- }
-
- fun moveSong(from: Int, to: Int) {
- if (from == to) return
- val currentPosition = position
- val songToMove = playingQueue.removeAt(from)
- playingQueue.add(to, songToMove)
- if (shuffleMode == SHUFFLE_MODE_NONE) {
- val tmpSong = originalPlayingQueue.removeAt(from)
- originalPlayingQueue.add(to, tmpSong)
- }
- if (currentPosition in to..(from - 1)) {
- position = currentPosition + 1
- } else if (currentPosition in (from + 1)..to) {
- position = currentPosition - 1
- } else if (from == currentPosition) {
- position = to
- }
- notifyChange(QUEUE_CHANGED)
- }
-
- fun clearQueue() {
- playingQueue.clear()
- originalPlayingQueue.clear()
-
- position = -1
- notifyChange(QUEUE_CHANGED)
- }
-
- fun playSongAt(position: Int) {
- // handle this on the handlers thread to avoid blocking the ui thread
- playerHandler!!.removeMessages(PLAY_SONG)
- playerHandler!!.obtainMessage(PLAY_SONG, position, 0).sendToTarget()
- }
-
- private fun playSongAtImpl(position: Int) {
- if (openTrackAndPrepareNextAt(position)) {
- play()
- } else {
- Toast.makeText(this, resources.getString(R.string.unplayable_file), Toast.LENGTH_SHORT).show()
- }
- }
-
- fun pause() {
- pausedByTransientLossOfFocus = false
- if (playback!!.isPlaying) {
- playback!!.pause()
- notifyChange(PLAY_STATE_CHANGED)
- }
- }
-
- fun play() {
- synchronized(this) {
- if (requestFocus()) {
- if (!playback!!.isPlaying) {
- if (!playback!!.isInitialized) {
- playSongAt(position)
- } else {
- playback!!.start()
- if (!becomingNoisyReceiverRegistered) {
- registerReceiver(becomingNoisyReceiver, becomingNoisyReceiverIntentFilter)
- becomingNoisyReceiverRegistered = true
- }
- if (notHandledMetaChangedForCurrentTrack) {
- handleChangeInternal(META_CHANGED)
- notHandledMetaChangedForCurrentTrack = false
- }
- notifyChange(PLAY_STATE_CHANGED)
-
- // fixes a bug where the volume would stay ducked because the AudioManager.AUDIOFOCUS_GAIN event is not sent
- playerHandler!!.removeMessages(DUCK)
- playerHandler!!.sendEmptyMessage(UN_DUCK)
- }
- }
- } else {
- Toast.makeText(this, resources.getString(R.string.audio_focus_denied), Toast.LENGTH_SHORT).show()
- }
- }
- }
-
- fun playSongs(songs: ArrayList?, shuffleMode: Int) {
- if (songs != null && !songs.isEmpty()) {
- if (shuffleMode == SHUFFLE_MODE_SHUFFLE) {
- var startPosition = 0
- if (!songs.isEmpty()) {
- startPosition = Random().nextInt(songs.size)
- }
- openQueue(songs, startPosition, false)
- setShuffleMode(shuffleMode)
- } else {
- openQueue(songs, 0, false)
- }
- play()
- } else {
- Toast.makeText(applicationContext, R.string.playlist_is_empty, Toast.LENGTH_LONG).show()
- }
- }
-
- fun playPreviousSong(force: Boolean) {
- playSongAt(getPreviousPosition(force))
- }
-
- fun back(force: Boolean) {
- if (songProgressMillis > 2000) {
- seek(0)
- } else {
- playPreviousSong(force)
- }
- }
-
- private fun getPreviousPosition(force: Boolean): Int {
- var newPosition = position - 1
- when (repeatMode) {
- REPEAT_MODE_ALL -> if (newPosition < 0) {
- newPosition = playingQueue.size - 1
- }
- REPEAT_MODE_THIS -> if (force) {
- if (newPosition < 0) {
- newPosition = playingQueue.size - 1
- }
- } else {
- newPosition = position
- }
- REPEAT_MODE_NONE -> if (newPosition < 0) {
- newPosition = 0
- }
- else -> if (newPosition < 0) {
- newPosition = 0
- }
- }
- return newPosition
- }
-
- fun getQueueDurationMillis(position: Int): Long {
- var duration: Long = 0
- for (i in position + 1 until playingQueue.size)
- duration += playingQueue[i].duration
- return duration
- }
-
- fun seek(millis: Int): Int {
- synchronized(this) {
- try {
- val newPosition = playback!!.seek(millis)
- throttledSeekHandler!!.notifySeek()
- return newPosition
- } catch (e: Exception) {
- return -1
- }
-
- }
- }
-
- fun cycleRepeatMode() {
- repeatMode = when (repeatMode) {
- REPEAT_MODE_NONE -> REPEAT_MODE_ALL
- REPEAT_MODE_ALL -> REPEAT_MODE_THIS
- else -> REPEAT_MODE_NONE
- }
- }
-
- fun toggleShuffle() {
- if (shuffleMode == SHUFFLE_MODE_NONE) {
- setShuffleMode(SHUFFLE_MODE_SHUFFLE)
- } else {
- setShuffleMode(SHUFFLE_MODE_NONE)
- }
- }
-
-
- private fun notifyChange(what: String) {
- handleAndSendChangeInternal(what)
- sendPublicIntent(what)
- }
-
- private fun handleAndSendChangeInternal(what: String) {
- handleChangeInternal(what)
- sendChangeInternal(what)
- }
-
- // to let other apps know whats playing. i.E. last.fm (scrobbling) or musixmatch
- @SuppressLint("WrongConstant")
- private fun sendPublicIntent(what: String) {
- val intent = Intent(what.replace(RETRO_MUSIC_PACKAGE_NAME, MUSIC_PACKAGE_NAME))
-
- val song = currentSong
-
- intent.putExtra("id", song.id)
- intent.putExtra("artist", song.artistName)
- intent.putExtra("album", song.albumName)
- intent.putExtra("track", song.title)
- intent.putExtra("duration", song.duration)
- intent.putExtra("position", songProgressMillis.toLong())
- intent.putExtra("playing", isPlaying)
- intent.putExtra("scrobbling_source", RETRO_MUSIC_PACKAGE_NAME)
-
- sendStickyBroadcast(intent)
-
- }
-
- private fun sendChangeInternal(what: String) {
- sendBroadcast(Intent(what))
- }
-
- private fun handleChangeInternal(what: String) {
- when (what) {
- PLAY_STATE_CHANGED -> {
- updateNotification()
- updateMediaSessionPlaybackState()
- val isPlaying = isPlaying
- if (!isPlaying && songProgressMillis > 0) {
- savePositionInTrack()
- }
- songPlayCountHelper.notifyPlayStateChanged(isPlaying)
- }
- META_CHANGED -> {
- updateNotification()
- updateMediaSessionMetaData()
- savePosition()
- savePositionInTrack()
- val currentSong = currentSong
- HistoryStore.getInstance(this).addSongId(currentSong.id.toLong())
- if (songPlayCountHelper.shouldBumpPlayCount()) {
- SongPlayCountStore.getInstance(this).bumpPlayCount(songPlayCountHelper.song.id.toLong())
- }
- songPlayCountHelper.notifySongChanged(currentSong)
- }
- QUEUE_CHANGED -> {
- updateMediaSessionMetaData() // because playing queue size might have changed
- saveState()
- if (playingQueue.size > 0) {
- prepareNext()
- } else {
- playingNotification!!.stop()
- }
- }
- }
- }
-
- fun releaseWakeLock() {
- if (wakeLock!!.isHeld) {
- wakeLock!!.release()
- }
- }
-
- private fun acquireWakeLock(milli: Long) {
- wakeLock!!.acquire(milli)
- }
-
- override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
- when (key) {
- PreferenceUtil.GAPLESS_PLAYBACK -> if (sharedPreferences.getBoolean(key, false)) {
- prepareNext()
- } else {
- playback!!.setNextDataSource(null)
- }
- PreferenceUtil.ALBUM_ART_ON_LOCKSCREEN, PreferenceUtil.BLURRED_ALBUM_ART -> updateMediaSessionMetaData()
- PreferenceUtil.COLORED_NOTIFICATION, PreferenceUtil.DOMINANT_COLOR -> updateNotification()
- PreferenceUtil.CLASSIC_NOTIFICATION -> {
- initNotification()
- updateNotification()
- }
- PreferenceUtil.TOGGLE_HEADSET -> registerHeadsetEvents()
- }
- }
-
- private fun registerHeadsetEvents() {
- if (!headsetReceiverRegistered && PreferenceUtil.getInstance().headsetPlugged) {
- registerReceiver(headsetReceiver, headsetReceiverIntentFilter)
- headsetReceiverRegistered = true
- }
- }
-
- override fun onTrackWentToNext() {
- playerHandler!!.sendEmptyMessage(TRACK_WENT_TO_NEXT)
- }
-
- override fun onTrackEnded() {
- acquireWakeLock(30000)
- playerHandler!!.sendEmptyMessage(TRACK_ENDED)
- }
-
-
- inner class QueueSaveHandler internal constructor(service: MusicService, looper: Looper) : Handler(looper) {
- val mService: WeakReference = WeakReference(service)
-
- override fun handleMessage(msg: Message) {
- val service = mService.get()
- when (msg.what) {
- SAVE_QUEUES -> service!!.saveQueuesImpl()
- }
- }
- }
-
- inner class PlaybackHandler internal constructor(service: MusicService, looper: Looper) : Handler(looper) {
- val mService: WeakReference = WeakReference(service)
- var currentDuckVolume = 1.0f
-
- override fun handleMessage(msg: Message) {
- val service = mService.get() ?: return
-
- when (msg.what) {
- DUCK -> {
- if (PreferenceUtil.getInstance().audioDucking()) {
- currentDuckVolume -= .05f
- if (currentDuckVolume > .2f) {
- sendEmptyMessageDelayed(DUCK, 10)
- } else {
- currentDuckVolume = .2f
- }
- } else {
- currentDuckVolume = 1f
- }
- service.playback!!.setVolume(currentDuckVolume)
- }
-
- UN_DUCK -> {
- if (PreferenceUtil.getInstance().audioDucking()) {
- currentDuckVolume += .03f
- if (currentDuckVolume < 1f) {
- sendEmptyMessageDelayed(UN_DUCK, 10)
- } else {
- currentDuckVolume = 1f
- }
- } else {
- currentDuckVolume = 1f
- }
- service.playback!!.setVolume(currentDuckVolume)
- }
-
- TRACK_WENT_TO_NEXT -> if (service.repeatMode == REPEAT_MODE_NONE && service.isLastTrack) {
- service.pause()
- service.seek(0)
- } else {
- service.position = service.nextPosition
- service.prepareNextImpl()
- service.notifyChange(META_CHANGED)
- }
-
- TRACK_ENDED -> {
- if (service.repeatMode == REPEAT_MODE_NONE && service.isLastTrack) {
- service.notifyChange(PLAY_STATE_CHANGED)
- service.seek(0)
- } else {
- service.playNextSong(false)
- }
- sendEmptyMessage(RELEASE_WAKELOCK)
- }
-
- RELEASE_WAKELOCK -> service.releaseWakeLock()
-
- PLAY_SONG -> service.playSongAtImpl(msg.arg1)
-
- SET_POSITION -> {
- service.openTrackAndPrepareNextAt(msg.arg1)
- service.notifyChange(PLAY_STATE_CHANGED)
- }
-
- PREPARE_NEXT -> service.prepareNextImpl()
-
- RESTORE_QUEUES -> service.restoreQueuesAndPositionIfNecessary()
-
- FOCUS_CHANGE -> when (msg.arg1) {
- AudioManager.AUDIOFOCUS_GAIN -> {
- if (!service.isPlaying && service.pausedByTransientLossOfFocus) {
- service.play()
- service.pausedByTransientLossOfFocus = false
- }
- removeMessages(DUCK)
- sendEmptyMessage(UN_DUCK)
- }
-
- AudioManager.AUDIOFOCUS_LOSS ->
- // Lost focus for an unbounded amount of time: stop playback and release media playback
- service.pause()
-
- AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
- // Lost focus for a short time, but we have to stop
- // playback. We don't release the media playback because playback
- // is likely to resume
- val wasPlaying = service.isPlaying
- service.pause()
- service.pausedByTransientLossOfFocus = wasPlaying
- }
-
- AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
- // Lost focus for a short time, but it's ok to keep playing
- // at an attenuated level
- removeMessages(UN_DUCK)
- sendEmptyMessage(DUCK)
- }
- }
- }
- }
- }
-
- inner class SongPlayCountHelper {
-
- private val stopWatch = StopWatch()
- var song = Song.EMPTY_SONG
- private set
-
- internal fun shouldBumpPlayCount(): Boolean {
- return song.duration * 0.5 < stopWatch.elapsedTime
- }
-
- internal fun notifySongChanged(song: Song) {
- synchronized(this) {
- stopWatch.reset()
- this.song = song
- }
- }
-
- internal fun notifyPlayStateChanged(isPlaying: Boolean) {
- synchronized(this) {
- if (isPlaying) {
- stopWatch.start()
- } else {
- stopWatch.pause()
- }
- }
- }
- }
-
- inner class MusicBinder : Binder() {
- val service: MusicService
- get() = this@MusicService
- }
-
- inner class MediaStoreObserver internal constructor(private val mHandler: Handler) : ContentObserver(mHandler), Runnable {
-
- override fun onChange(selfChange: Boolean) {
- // if a change is detected, remove any scheduled callback
- // then post a new one. This is intended to prevent closely
- // spaced events from generating multiple refresh calls
- mHandler.removeCallbacks(this)
- mHandler.postDelayed(this, 500)
- }
-
- override fun run() {
- // actually call refresh when the delayed callback fires
- // do not send a sticky broadcast here
- handleAndSendChangeInternal(MEDIA_STORE_CHANGED)
- }
- }
-
- inner class ThrottledSeekHandler internal constructor(private val mHandler: Handler) : Runnable {
-
- internal fun notifySeek() {
- mHandler.removeCallbacks(this)
- mHandler.postDelayed(this, 500)
- }
-
- override fun run() {
- savePositionInTrack()
- sendPublicIntent(PLAY_STATE_CHANGED) // for musixmatch synced lyrics
- }
- }
-
- companion object {
- val TAG: String = MusicService::class.java.simpleName
-
- const val SAVED_POSITION = "POSITION"
- const val SAVED_POSITION_IN_TRACK = "POSITION_IN_TRACK"
- const val SAVED_SHUFFLE_MODE = "SHUFFLE_MODE"
- const val SAVED_REPEAT_MODE = "REPEAT_MODE"
-
- const val RELEASE_WAKELOCK = 0
- const val TRACK_ENDED = 1
- const val TRACK_WENT_TO_NEXT = 2
- const val PLAY_SONG = 3
- const val PREPARE_NEXT = 4
- const val SET_POSITION = 5
- const val RESTORE_QUEUES = 9
- const val SHUFFLE_MODE_NONE = 0
- const val SHUFFLE_MODE_SHUFFLE = 1
- const val REPEAT_MODE_NONE = 0
- const val REPEAT_MODE_ALL = 1
- const val REPEAT_MODE_THIS = 2
- const val SAVE_QUEUES = 0
- const val FOCUS_CHANGE = 6
- const val DUCK = 7
- const val UN_DUCK = 8
- const val MEDIA_SESSION_ACTIONS = (PlaybackStateCompat.ACTION_PLAY
- or PlaybackStateCompat.ACTION_PAUSE
- or PlaybackStateCompat.ACTION_PLAY_PAUSE
- or PlaybackStateCompat.ACTION_SKIP_TO_NEXT
- or PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS
- or PlaybackStateCompat.ACTION_STOP
- or PlaybackStateCompat.ACTION_SEEK_TO)
-
- private fun getTrackUri(song: Song): String {
- return MusicUtil.getSongFileUri(song.id).toString()
- }
-
- private fun copy(bitmap: Bitmap): Bitmap? {
- var config: Bitmap.Config? = bitmap.config
- if (config == null) {
- config = Bitmap.Config.RGB_565
- }
- try {
- return bitmap.copy(config, false)
- } catch (e: OutOfMemoryError) {
- e.printStackTrace()
- return null
- }
-
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/AlbumDetailsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/AlbumDetailsActivity.kt
index af628a2c..1876a809 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/AlbumDetailsActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/AlbumDetailsActivity.kt
@@ -13,7 +13,6 @@ import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import butterknife.ButterKnife
-import butterknife.OnClick
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.TintHelper
@@ -49,9 +48,9 @@ import java.util.*
class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContract.AlbumDetailsView {
- private var albumDetailsPresenter: AlbumDetailsPresenter? = null
+ private lateinit var albumDetailsPresenter: AlbumDetailsPresenter
+ private lateinit var simpleSongAdapter: SimpleSongAdapter
- private var adapter: SimpleSongAdapter? = null
var album: Album? = null
private set
@@ -82,13 +81,12 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
val albumId = intent.getIntExtra(EXTRA_ALBUM_ID, -1)
albumDetailsPresenter = AlbumDetailsPresenter(this, albumId)
- albumDetailsPresenter!!.subscribe()
+ albumDetailsPresenter.subscribe()
setupRecyclerView()
setupToolbarMarginHeight()
-
- contentContainer.setOnScrollChangeListener { v: NestedScrollView?, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int ->
+ contentContainer.setOnScrollChangeListener { _: NestedScrollView?, _: Int, scrollY: Int, _: Int, oldScrollY: Int ->
run {
if (scrollY > oldScrollY) {
actionShuffleAll!!.setShowTitle(false)
@@ -98,31 +96,40 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
}
}
}
+
+ actionShuffleAll.setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(album!!.songs!!, true) }
+ artistImage.setOnClickListener {
+ val artistPairs = arrayOf>(Pair.create(image, resources.getString(R.string.transition_artist_image)))
+ NavigationUtil.goToArtist(this, album!!.artistId, *artistPairs)
+ }
}
private fun setupRecyclerView() {
- adapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song)
+ simpleSongAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song)
recyclerView.apply {
layoutManager = LinearLayoutManager(this@AlbumDetailsActivity)
itemAnimator = DefaultItemAnimator()
isNestedScrollingEnabled = false
- adapter = adapter
+ adapter = simpleSongAdapter
}
}
private fun setupToolbarMarginHeight() {
- val primaryColor = ThemeStore.primaryColor(this)
- TintHelper.setTintAuto(contentContainer!!, primaryColor, true)
- if (collapsingToolbarLayout != null) {
- collapsingToolbarLayout!!.setContentScrimColor(primaryColor)
- collapsingToolbarLayout!!.setStatusBarScrimColor(ColorUtil.darkenColor(primaryColor))
- }
-
- toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
setSupportActionBar(toolbar)
-
supportActionBar!!.title = null
+ val primaryColor = ThemeStore.primaryColor(this)
+ TintHelper.setTintAuto(contentContainer!!, primaryColor, true)
+
+ if (collapsingToolbarLayout != null) {
+ collapsingToolbarLayout!!.apply {
+ setContentScrimColor(primaryColor)
+ setStatusBarScrimColor(ColorUtil.darkenColor(primaryColor))
+ }
+ }
+
+
+ toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
if (toolbar != null && !PreferenceUtil.getInstance().fullScreenMode) {
val params = toolbar!!.layoutParams as ViewGroup.MarginLayoutParams
@@ -131,45 +138,29 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
}
if (appBarLayout != null) {
- appBarLayout!!.addOnOffsetChangedListener(object : AppBarStateChangeListener() {
- override fun onStateChanged(appBarLayout: AppBarLayout, state: AppBarStateChangeListener.State) {
- val color: Int
- when (state) {
- AppBarStateChangeListener.State.COLLAPSED -> {
- setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(this@AlbumDetailsActivity)))
- color = ThemeStore.primaryColor(this@AlbumDetailsActivity)
- }
- AppBarStateChangeListener.State.EXPANDED, AppBarStateChangeListener.State.IDLE -> {
- setLightStatusbar(false)
- color = Color.TRANSPARENT
- }
- else -> {
- setLightStatusbar(false)
- color = Color.TRANSPARENT
+ appBarLayout!!.apply {
+ addOnOffsetChangedListener(object : AppBarStateChangeListener() {
+ override fun onStateChanged(appBarLayout: AppBarLayout, state: AppBarStateChangeListener.State) {
+ val color: Int = when (state) {
+ AppBarStateChangeListener.State.COLLAPSED -> {
+ setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(this@AlbumDetailsActivity)))
+ ThemeStore.primaryColor(this@AlbumDetailsActivity)
+ }
+ AppBarStateChangeListener.State.EXPANDED, AppBarStateChangeListener.State.IDLE -> {
+ setLightStatusbar(false)
+ Color.TRANSPARENT
+ }
}
+ ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(this@AlbumDetailsActivity, toolbar, color)
}
- ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(this@AlbumDetailsActivity, toolbar, color)
- }
- })
- }
- }
-
- @OnClick(R.id.action_shuffle_all, R.id.artist_image)
- fun onViewClicked(view: View) {
- when (view.id) {
- R.id.artist_image -> {
- val artistPairs = arrayOf>(Pair.create(image, resources.getString(R.string.transition_artist_image)))
- NavigationUtil.goToArtist(this, album!!.artistId, *artistPairs)
- }
- R.id.action_shuffle_all -> if (album!!.songs != null) {
- MusicPlayerRemote.openAndShuffleQueue(album!!.songs!!, true)
+ })
}
}
}
override fun onPause() {
super.onPause()
- albumDetailsPresenter!!.unsubscribe()
+ albumDetailsPresenter.unsubscribe()
}
override fun loading() {
@@ -196,7 +187,8 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
loadAlbumCover()
loadMoreFrom(album)
- adapter!!.swapDataSet(album.songs)
+
+ simpleSongAdapter.swapDataSet(album.songs)
}
private fun loadMoreFrom(album: Album) {
@@ -213,20 +205,19 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
})
}
- val albums = ArtistLoader.getArtist(this, album.artistId)
- .blockingFirst().albums
+ val albums = ArtistLoader.getArtist(this, album.artistId).blockingFirst().albums
albums!!.remove(album)
if (!albums.isEmpty()) {
moreTitle.visibility = View.VISIBLE
- moreRecyclerView!!.visibility = View.VISIBLE
+ moreRecyclerView.visibility = View.VISIBLE
} else {
return
}
moreTitle.text = String.format("More from %s", album.artistName)
val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null)
- moreRecyclerView!!.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false)
- moreRecyclerView!!.adapter = albumAdapter
+ moreRecyclerView.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false)
+ moreRecyclerView.adapter = albumAdapter
}
private fun loadAlbumCover() {
@@ -262,7 +253,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
var sortOrder: String? = null
- val songs = adapter!!.dataSet
+ val songs = simpleSongAdapter.dataSet
when (item.itemId) {
R.id.action_play_next -> {
MusicPlayerRemote.playNext(songs)
@@ -327,7 +318,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
}
private fun reload() {
- albumDetailsPresenter!!.subscribe()
+ albumDetailsPresenter.subscribe()
}
companion object {
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/ArtistDetailActivity.java b/app/src/main/java/code/name/monkey/retromusic/ui/activities/ArtistDetailActivity.java
deleted file mode 100755
index 6bf6346e..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/ArtistDetailActivity.java
+++ /dev/null
@@ -1,458 +0,0 @@
-package code.name.monkey.retromusic.ui.activities;
-
-import android.content.Intent;
-import android.content.res.ColorStateList;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.text.Html;
-import android.text.Spanned;
-import android.transition.Slide;
-import android.view.Gravity;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.view.animation.AnimationUtils;
-import android.widget.ImageView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.bumptech.glide.Glide;
-import com.google.android.material.appbar.AppBarLayout;
-import com.google.android.material.appbar.CollapsingToolbarLayout;
-
-import java.util.ArrayList;
-import java.util.Locale;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.widget.AppCompatTextView;
-import androidx.appcompat.widget.Toolbar;
-import androidx.core.app.ActivityCompat;
-import androidx.core.widget.NestedScrollView;
-import androidx.recyclerview.widget.DefaultItemAnimator;
-import androidx.recyclerview.widget.GridLayoutManager;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import code.name.monkey.appthemehelper.ThemeStore;
-import code.name.monkey.appthemehelper.util.ColorUtil;
-import code.name.monkey.appthemehelper.util.TintHelper;
-import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog;
-import code.name.monkey.retromusic.glide.ArtistGlideRequest;
-import code.name.monkey.retromusic.glide.RetroMusicColoredTarget;
-import code.name.monkey.retromusic.helper.MusicPlayerRemote;
-import code.name.monkey.retromusic.misc.AppBarStateChangeListener;
-import code.name.monkey.retromusic.model.Artist;
-import code.name.monkey.retromusic.model.Song;
-import code.name.monkey.retromusic.mvp.contract.ArtistDetailContract;
-import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter;
-import code.name.monkey.retromusic.rest.LastFMRestClient;
-import code.name.monkey.retromusic.rest.model.LastFmArtist;
-import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity;
-import code.name.monkey.retromusic.ui.adapter.album.AlbumAdapter;
-import code.name.monkey.retromusic.ui.adapter.album.HorizontalAlbumAdapter;
-import code.name.monkey.retromusic.ui.adapter.song.SimpleSongAdapter;
-import code.name.monkey.retromusic.util.CustomArtistImageUtil;
-import code.name.monkey.retromusic.util.DensityUtil;
-import code.name.monkey.retromusic.util.MusicUtil;
-import code.name.monkey.retromusic.util.PreferenceUtil;
-import code.name.monkey.retromusic.util.RetroUtil;
-import code.name.monkey.retromusic.views.CollapsingFAB;
-import retrofit2.Call;
-import retrofit2.Callback;
-import retrofit2.Response;
-
-public class ArtistDetailActivity extends AbsSlidingMusicPanelActivity implements
- ArtistDetailContract.ArtistsDetailsView {
-
- public static final String EXTRA_ARTIST_ID = "extra_artist_id";
- private static final int REQUEST_CODE_SELECT_IMAGE = 9003;
- @BindView(R.id.app_bar)
- @Nullable
- AppBarLayout appBarLayout;
-
- @BindView(R.id.collapsing_toolbar)
- @Nullable
- CollapsingToolbarLayout collapsingToolbarLayout;
-
- @BindView(R.id.image)
- ImageView image;
-
- @BindView(R.id.biography)
- TextView biographyTextView;
-
- @BindView(R.id.recycler_view)
- RecyclerView recyclerView;
-
- @BindView(R.id.album_recycler_view)
- RecyclerView albumRecyclerView;
-
- @BindView(R.id.album_title)
- AppCompatTextView albumTitle;
-
- @BindView(R.id.song_title)
- AppCompatTextView songTitle;
-
- @BindView(R.id.biography_title)
- AppCompatTextView biographyTitle;
-
- @BindView(R.id.title)
- TextView title;
-
- @BindView(R.id.text)
- TextView text;
-
- @BindView(R.id.action_shuffle_all)
- CollapsingFAB shuffleButton;
-
- @BindView(R.id.gradient_background)
- @Nullable
- View background;
-
- @BindView(R.id.image_container)
- @Nullable
- View imageContainer;
-
- @BindView(R.id.content)
- NestedScrollView contentContainer;
-
- @BindView(R.id.toolbar)
- Toolbar toolbar;
-
- @Nullable
- private Spanned biography;
- private Artist artist;
- private LastFMRestClient lastFMRestClient;
- private ArtistDetailsPresenter artistDetailsPresenter;
- private SimpleSongAdapter songAdapter;
- private AlbumAdapter albumAdapter;
- private boolean forceDownload;
-
- void setupWindowTransistion() {
- Slide slide = new Slide(Gravity.BOTTOM);
- slide.setInterpolator(
- AnimationUtils.loadInterpolator(this, android.R.interpolator.linear_out_slow_in));
- getWindow().setEnterTransition(slide);
-
- }
-
-
- @Override
- protected View createContentView() {
- return wrapSlidingMusicPanel(R.layout.activity_artist_details);
- }
-
- @Override
- protected void onCreate(Bundle bundle) {
- setDrawUnderStatusBar();
- setupWindowTransistion();
- super.onCreate(bundle);
- ButterKnife.bind(this);
-
- toggleBottomNavigationView(true);
- setNavigationbarColorAuto();
- setLightNavigationBar(true);
-
- ActivityCompat.postponeEnterTransition(this);
-
- lastFMRestClient = new LastFMRestClient(this);
-
- setUpViews();
-
- artistDetailsPresenter = new ArtistDetailsPresenter(this, getIntent().getExtras());
- artistDetailsPresenter.subscribe();
-
- contentContainer.setOnScrollChangeListener((NestedScrollView.OnScrollChangeListener) (v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
- if (scrollY > oldScrollY) {
- shuffleButton.setShowTitle(false);
- }
- if (scrollY < oldScrollY) {
- shuffleButton.setShowTitle(true);
- }
- });
- }
-
- private void setUpViews() {
- setupRecyclerView();
- setupToolbarMarginHeight();
- setupContainerHeight();
- }
-
- private void setupContainerHeight() {
- if (imageContainer != null) {
- LayoutParams params = imageContainer.getLayoutParams();
- params.width = DensityUtil.getScreenHeight(this) / 2;
- imageContainer.setLayoutParams(params);
- }
- }
-
- private void setupToolbarMarginHeight() {
- int primaryColor = ThemeStore.primaryColor(this);
- TintHelper.setTintAuto(contentContainer, primaryColor, true);
- if (collapsingToolbarLayout != null) {
- collapsingToolbarLayout.setContentScrimColor(primaryColor);
- collapsingToolbarLayout.setStatusBarScrimColor(ColorUtil.darkenColor(primaryColor));
- }
-
- toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
- setSupportActionBar(toolbar);
- //noinspection ConstantConditions
- getSupportActionBar().setTitle(null);
-
-
- if (toolbar != null && !PreferenceUtil.getInstance().getFullScreenMode()) {
- ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) toolbar.getLayoutParams();
- params.topMargin = RetroUtil.getStatusBarHeight( );
- toolbar.setLayoutParams(params);
- }
-
- if (appBarLayout != null) {
- appBarLayout.addOnOffsetChangedListener(new AppBarStateChangeListener() {
- @Override
- public void onStateChanged(AppBarLayout appBarLayout, State state) {
- int color;
- switch (state) {
- case COLLAPSED:
- setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(appBarLayout.getContext())));
- color = ThemeStore.primaryColor(appBarLayout.getContext());
- break;
- default:
- case EXPANDED:
- case IDLE:
- setLightStatusbar(false);
- color = Color.TRANSPARENT;
- break;
- }
- ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(appBarLayout.getContext(), toolbar, color);
- }
- });
- }
- }
-
- private void setupRecyclerView() {
- albumAdapter = new HorizontalAlbumAdapter(this, new ArrayList<>(), false, null);
- albumRecyclerView.setItemAnimator(new DefaultItemAnimator());
- albumRecyclerView.setLayoutManager(new GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false));
- albumRecyclerView.setAdapter(albumAdapter);
-
- songAdapter = new SimpleSongAdapter(this, new ArrayList<>(), R.layout.item_song);
- recyclerView.setItemAnimator(new DefaultItemAnimator());
- recyclerView.setLayoutManager(new LinearLayoutManager(this));
- recyclerView.setAdapter(songAdapter);
- }
-
-
- @Override
- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- super.onActivityResult(requestCode, resultCode, data);
- switch (requestCode) {
- case REQUEST_CODE_SELECT_IMAGE:
- if (resultCode == RESULT_OK) {
- CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist, data.getData());
- }
- break;
- default:
- if (resultCode == RESULT_OK) {
- reload();
- }
- break;
- }
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- artistDetailsPresenter.unsubscribe();
- }
-
- @Override
- public void loading() {
- }
-
- @Override
- public void showEmptyView() {
-
- }
-
- @Override
- public void completed() {
- ActivityCompat.startPostponedEnterTransition(this);
- }
-
- @Override
- public void showData(Artist artist) {
- setArtist(artist);
- }
-
- private Artist getArtist() {
- if (artist == null) {
- artist = new Artist();
- }
- return artist;
- }
-
- private void setArtist(Artist artist) {
- if (artist.getSongCount() <= 0) {
- finish();
- }
- this.artist = artist;
- loadArtistImage();
-
- if (RetroUtil.isAllowedToDownloadMetadata(this)) {
- loadBiography();
- }
- title.setText(artist.getName());
- text.setText(String.format("%s • %s", MusicUtil.getArtistInfoString(this, artist), MusicUtil
- .getReadableDurationString(MusicUtil.getTotalDuration(this, artist.getSongs()))));
-
- songAdapter.swapDataSet(artist.getSongs());
- albumAdapter.swapDataSet(artist.getAlbums());
- }
-
- private void loadBiography() {
- loadBiography(Locale.getDefault().getLanguage());
- }
-
- private void loadBiography(@Nullable final String lang) {
- biography = null;
-
- lastFMRestClient.getApiService()
- .getArtistInfo(getArtist().getName(), lang, null)
- .enqueue(new Callback() {
- @Override
- public void onResponse(@NonNull Call call,
- @NonNull Response response) {
- final LastFmArtist lastFmArtist = response.body();
- if (lastFmArtist != null && lastFmArtist.getArtist() != null) {
- final String bioContent = lastFmArtist.getArtist().getBio().getContent();
- if (bioContent != null && !bioContent.trim().isEmpty()) {
- //TransitionManager.beginDelayedTransition(titleContainer);
- biographyTextView.setVisibility(View.VISIBLE);
- biographyTitle.setVisibility(View.VISIBLE);
- biography = Html.fromHtml(bioContent);
- biographyTextView.setText(biography);
- }
- }
-
- // If the "lang" parameter is set and no biography is given, retry with default language
- if (biography == null && lang != null) {
- loadBiography(null);
- }
- }
-
- @Override
- public void onFailure(@NonNull Call call, @NonNull Throwable t) {
- t.printStackTrace();
- biography = null;
- }
- });
- }
-
- @OnClick(R.id.biography)
- void toggleArtistBiography() {
- if (biographyTextView.getMaxLines() == 4) {
- biographyTextView.setMaxLines(Integer.MAX_VALUE);
- } else {
- biographyTextView.setMaxLines(4);
- }
- }
-
- private void loadArtistImage() {
- ArtistGlideRequest.Builder.from(Glide.with(this), artist)
- .forceDownload(forceDownload)
- .generatePalette(this).build()
- .dontAnimate()
- .into(new RetroMusicColoredTarget(image) {
- @Override
- public void onColorReady(int color) {
- setColors(color);
- }
- });
- forceDownload = false;
- }
-
- private void setColors(int color) {
-
- int textColor = PreferenceUtil.getInstance().getAdaptiveColor() ? color : ThemeStore.accentColor(this);
-
- albumTitle.setTextColor(textColor);
- songTitle.setTextColor(textColor);
- biographyTitle.setTextColor(textColor);
-
- shuffleButton.setColor(textColor);
-
- if (background != null) {
- background.setBackgroundTintList(ColorStateList.valueOf(color));
- }
- findViewById(R.id.root).setBackgroundColor(ThemeStore.primaryColor(this));
- }
-
- @OnClick({R.id.action_shuffle_all})
- public void onViewClicked(View view) {
- switch (view.getId()) {
- case R.id.action_shuffle_all:
- MusicPlayerRemote.INSTANCE.openAndShuffleQueue(getArtist().getSongs(), true);
- break;
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- return handleSortOrderMenuItem(item);
- }
-
- private boolean handleSortOrderMenuItem(@NonNull MenuItem item) {
- final ArrayList songs = getArtist().getSongs();
- switch (item.getItemId()) {
- case android.R.id.home:
- super.onBackPressed();
- return true;
- case R.id.action_play_next:
- MusicPlayerRemote.INSTANCE.playNext(songs);
- return true;
- case R.id.action_add_to_current_playing:
- MusicPlayerRemote.INSTANCE.enqueue(songs);
- return true;
- case R.id.action_add_to_playlist:
- AddToPlaylistDialog.create(songs).show(getSupportFragmentManager(), "ADD_PLAYLIST");
- return true;
- case R.id.action_set_artist_image:
- Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
- intent.setType("image/*");
- startActivityForResult(
- Intent.createChooser(intent, getString(R.string.pick_from_local_storage)),
- REQUEST_CODE_SELECT_IMAGE);
- return true;
- case R.id.action_reset_artist_image:
- Toast.makeText(ArtistDetailActivity.this, getResources().getString(R.string.updating),
- Toast.LENGTH_SHORT).show();
- CustomArtistImageUtil.getInstance(ArtistDetailActivity.this).resetCustomArtistImage(artist);
- forceDownload = true;
- return true;
- }
- return true;
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_artist_detail, menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public void onMediaStoreChanged() {
- super.onMediaStoreChanged();
- reload();
- }
-
- private void reload() {
- artistDetailsPresenter.unsubscribe();
- artistDetailsPresenter.subscribe();
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/ArtistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/ArtistDetailActivity.kt
new file mode 100755
index 00000000..c47a6074
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/ArtistDetailActivity.kt
@@ -0,0 +1,363 @@
+package code.name.monkey.retromusic.ui.activities
+
+import android.app.Activity
+import android.content.Intent
+import android.graphics.Color
+import android.os.Build
+import android.os.Bundle
+import android.text.Html
+import android.text.Spanned
+import android.transition.Slide
+import android.view.*
+import android.view.animation.AnimationUtils
+import android.widget.Toast
+import androidx.core.app.ActivityCompat
+import androidx.core.widget.NestedScrollView
+import androidx.recyclerview.widget.DefaultItemAnimator
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import butterknife.ButterKnife
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.appthemehelper.util.ColorUtil
+import code.name.monkey.appthemehelper.util.TintHelper
+import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
+import code.name.monkey.retromusic.glide.ArtistGlideRequest
+import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.misc.AppBarStateChangeListener
+import code.name.monkey.retromusic.model.Artist
+import code.name.monkey.retromusic.mvp.contract.ArtistDetailContract
+import code.name.monkey.retromusic.mvp.presenter.ArtistDetailsPresenter
+import code.name.monkey.retromusic.rest.LastFMRestClient
+import code.name.monkey.retromusic.rest.model.LastFmArtist
+import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity
+import code.name.monkey.retromusic.ui.adapter.album.AlbumAdapter
+import code.name.monkey.retromusic.ui.adapter.album.HorizontalAlbumAdapter
+import code.name.monkey.retromusic.ui.adapter.song.SimpleSongAdapter
+import code.name.monkey.retromusic.util.*
+import com.bumptech.glide.Glide
+import com.google.android.material.appbar.AppBarLayout
+import kotlinx.android.synthetic.main.activity_artist_content.*
+import kotlinx.android.synthetic.main.activity_artist_details.*
+import retrofit2.Call
+import retrofit2.Callback
+import retrofit2.Response
+import java.util.*
+
+class ArtistDetailActivity : AbsSlidingMusicPanelActivity(), ArtistDetailContract.ArtistsDetailsView {
+
+ private var biography: Spanned? = null
+ private var artist: Artist? = null
+ private var lastFMRestClient: LastFMRestClient? = null
+ private var artistDetailsPresenter: ArtistDetailsPresenter? = null
+ private var songAdapter: SimpleSongAdapter? = null
+ private var albumAdapter: AlbumAdapter? = null
+ private var forceDownload: Boolean = false
+
+ private fun setupWindowTransistion() {
+ val slide = Slide(Gravity.BOTTOM)
+ slide.interpolator = AnimationUtils.loadInterpolator(this, android.R.interpolator.linear_out_slow_in)
+ window.enterTransition = slide
+ }
+
+
+ override fun createContentView(): View {
+ return wrapSlidingMusicPanel(R.layout.activity_artist_details)
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ setDrawUnderStatusBar()
+ setupWindowTransistion()
+ super.onCreate(savedInstanceState)
+ ButterKnife.bind(this)
+
+ toggleBottomNavigationView(true)
+ setNavigationbarColorAuto()
+ setLightNavigationBar(true)
+
+ ActivityCompat.postponeEnterTransition(this)
+
+ lastFMRestClient = LastFMRestClient(this)
+
+ setUpViews()
+
+ artistDetailsPresenter = ArtistDetailsPresenter(this, intent.extras)
+ artistDetailsPresenter!!.subscribe()
+
+ contentContainer.setOnScrollChangeListener { _: NestedScrollView?, _: Int, scrollY: Int, _: Int, oldScrollY: Int ->
+ run {
+ if (scrollY > oldScrollY) {
+ actionShuffleAll!!.setShowTitle(false)
+ }
+ if (scrollY < oldScrollY) {
+ actionShuffleAll!!.setShowTitle(true)
+ }
+ }
+ }
+
+ biographyText.setOnClickListener {
+ if (biographyText.maxLines == 4) {
+ biographyText.maxLines = Integer.MAX_VALUE
+ } else {
+ biographyText.maxLines = 4
+ }
+ }
+ actionShuffleAll.setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(getArtist().songs, true) }
+ }
+
+ private fun setUpViews() {
+ setupRecyclerView()
+ setupToolbarMarginHeight()
+ setupContainerHeight()
+ }
+
+ private fun setupContainerHeight() {
+ if (imageContainer != null) {
+ val params = imageContainer!!.layoutParams
+ params.width = DensityUtil.getScreenHeight(this) / 2
+ imageContainer!!.layoutParams = params
+ }
+ }
+
+ private fun setupToolbarMarginHeight() {
+ val primaryColor = ThemeStore.primaryColor(this)
+ TintHelper.setTintAuto(contentContainer!!, primaryColor, true)
+ if (collapsingToolbar != null) {
+ collapsingToolbar!!.setContentScrimColor(primaryColor)
+ collapsingToolbar!!.setStatusBarScrimColor(ColorUtil.darkenColor(primaryColor))
+ }
+
+ toolbar!!.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
+ setSupportActionBar(toolbar)
+
+ supportActionBar!!.title = null
+
+
+ if (toolbar != null && !PreferenceUtil.getInstance().fullScreenMode) {
+ val params = toolbar!!.layoutParams as ViewGroup.MarginLayoutParams
+ params.topMargin = RetroUtil.getStatusBarHeight()
+ toolbar!!.layoutParams = params
+ }
+
+ if (appBarLayout != null) {
+ appBarLayout!!.addOnOffsetChangedListener(object : AppBarStateChangeListener() {
+ override fun onStateChanged(appBarLayout: AppBarLayout, state: AppBarStateChangeListener.State) {
+ val color: Int
+ when (state) {
+ AppBarStateChangeListener.State.COLLAPSED -> {
+ setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(appBarLayout.context)))
+ color = ThemeStore.primaryColor(appBarLayout.context)
+ }
+ AppBarStateChangeListener.State.EXPANDED, AppBarStateChangeListener.State.IDLE -> {
+ setLightStatusbar(false)
+ color = Color.TRANSPARENT
+ }
+
+ }
+ ToolbarContentTintHelper.setToolbarContentColorBasedOnToolbarColor(appBarLayout.context, toolbar, color)
+ }
+ })
+ }
+ }
+
+ private fun setupRecyclerView() {
+ albumAdapter = HorizontalAlbumAdapter(this, ArrayList(), false, null)
+ albumRecyclerView.apply {
+ itemAnimator = DefaultItemAnimator()
+ layoutManager = GridLayoutManager(this.context, 1, GridLayoutManager.HORIZONTAL, false)
+ adapter = albumAdapter
+ }
+ songAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song)
+ recyclerView.apply {
+ itemAnimator = DefaultItemAnimator()
+ layoutManager = LinearLayoutManager(this.context)
+ adapter = songAdapter
+ }
+ }
+
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ when (requestCode) {
+ REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
+ CustomArtistImageUtil.getInstance(this).setCustomArtistImage(artist, data!!.data)
+ }
+ else -> if (resultCode == Activity.RESULT_OK) {
+ reload()
+ }
+ }
+ }
+
+ override fun onPause() {
+ super.onPause()
+ artistDetailsPresenter!!.unsubscribe()
+ }
+
+ override fun loading() {}
+
+ override fun showEmptyView() {
+
+ }
+
+ override fun completed() {
+ ActivityCompat.startPostponedEnterTransition(this)
+ }
+
+ override fun showData(artist: Artist) {
+ setArtist(artist)
+ }
+
+ private fun getArtist(): Artist {
+ if (artist == null) {
+ artist = Artist()
+ }
+ return this.artist!!
+ }
+
+ private fun setArtist(artist: Artist) {
+ if (artist.songCount <= 0) {
+ finish()
+ }
+ this.artist = artist
+ loadArtistImage()
+
+ if (RetroUtil.isAllowedToDownloadMetadata(this)) {
+ loadBiography()
+ }
+ artistTitle.text = artist.name
+ text.text = String.format("%s • %s", MusicUtil.getArtistInfoString(this, artist), MusicUtil
+ .getReadableDurationString(MusicUtil.getTotalDuration(this, artist.songs)))
+
+ songAdapter!!.swapDataSet(artist.songs)
+ albumAdapter!!.swapDataSet(artist.albums!!)
+ }
+
+ private fun loadBiography(lang: String? = Locale.getDefault().language) {
+ biography = null
+
+ lastFMRestClient!!.apiService
+ .getArtistInfo(getArtist().name, lang, null)
+ .enqueue(object : Callback {
+ override fun onResponse(call: Call,
+ response: Response) {
+ val lastFmArtist = response.body()
+ if (lastFmArtist != null && lastFmArtist.artist != null) {
+ val bioContent = lastFmArtist.artist.bio.content
+ if (bioContent != null && !bioContent.trim { it <= ' ' }.isEmpty()) {
+ //TransitionManager.beginDelayedTransition(titleContainer);
+ biographyText.visibility = View.VISIBLE
+ biographyTitle.visibility = View.VISIBLE
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ biography = Html.fromHtml(bioContent, Html.FROM_HTML_MODE_LEGACY)
+ } else {
+ biography = Html.fromHtml(bioContent)
+ }
+ biographyText!!.text = biography
+ }
+ }
+
+ // If the "lang" parameter is set and no biography is given, retry with default language
+ if (biography == null && lang != null) {
+ loadBiography(null)
+ }
+ }
+
+ override fun onFailure(call: Call, t: Throwable) {
+ t.printStackTrace()
+ biography = null
+ }
+ })
+ }
+
+
+ private fun loadArtistImage() {
+ ArtistGlideRequest.Builder.from(Glide.with(this), artist)
+ .forceDownload(forceDownload)
+ .generatePalette(this).build()
+ .dontAnimate()
+ .into(object : RetroMusicColoredTarget(artistImage) {
+ override fun onColorReady(color: Int) {
+ setColors(color)
+ }
+ })
+ forceDownload = false
+ }
+
+ private fun setColors(color: Int) {
+
+ val textColor = if (PreferenceUtil.getInstance().adaptiveColor) color else ThemeStore.accentColor(this)
+
+ albumTitle.setTextColor(textColor)
+ songTitle.setTextColor(textColor)
+ biographyTitle.setTextColor(textColor)
+
+ actionShuffleAll.setColor(textColor)
+
+
+ findViewById(R.id.root).setBackgroundColor(ThemeStore.primaryColor(this))
+ }
+
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ return handleSortOrderMenuItem(item)
+ }
+
+ private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
+ val songs = getArtist().songs
+ when (item.itemId) {
+ android.R.id.home -> {
+ super.onBackPressed()
+ return true
+ }
+ R.id.action_play_next -> {
+ MusicPlayerRemote.playNext(songs)
+ return true
+ }
+ R.id.action_add_to_current_playing -> {
+ MusicPlayerRemote.enqueue(songs)
+ return true
+ }
+ R.id.action_add_to_playlist -> {
+ AddToPlaylistDialog.create(songs).show(supportFragmentManager, "ADD_PLAYLIST")
+ return true
+ }
+ R.id.action_set_artist_image -> {
+ val intent = Intent(Intent.ACTION_GET_CONTENT)
+ intent.type = "image/*"
+ startActivityForResult(Intent.createChooser(intent, getString(R.string.pick_from_local_storage)), REQUEST_CODE_SELECT_IMAGE)
+ return true
+ }
+ R.id.action_reset_artist_image -> {
+ Toast.makeText(this@ArtistDetailActivity, resources.getString(R.string.updating),
+ Toast.LENGTH_SHORT).show()
+ CustomArtistImageUtil.getInstance(this@ArtistDetailActivity).resetCustomArtistImage(artist)
+ forceDownload = true
+ return true
+ }
+ }
+ return true
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(R.menu.menu_artist_detail, menu)
+ return super.onCreateOptionsMenu(menu)
+ }
+
+ override fun onMediaStoreChanged() {
+ super.onMediaStoreChanged()
+ reload()
+ }
+
+ private fun reload() {
+ artistDetailsPresenter!!.unsubscribe()
+ artistDetailsPresenter!!.subscribe()
+ }
+
+ companion object {
+
+ const val EXTRA_ARTIST_ID = "extra_artist_id"
+ const val REQUEST_CODE_SELECT_IMAGE = 9003
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/ErrorHandlerActivity.java b/app/src/main/java/code/name/monkey/retromusic/ui/activities/ErrorHandlerActivity.java
index 5a0ecd4c..10253ff9 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/ErrorHandlerActivity.java
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/ErrorHandlerActivity.java
@@ -1 +1 @@
-package code.name.monkey.retromusic.ui.activities;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import butterknife.OnClick;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.RetroApplication;
public class ErrorHandlerActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_error_handler);
}
@OnClick(R.id.clear_app_data)
void clearAppDate(View view) {
RetroApplication.Companion.deleteAppData();
}
}
\ No newline at end of file
+package code.name.monkey.retromusic.ui.activities;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import butterknife.OnClick;
import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.App;
public class ErrorHandlerActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_error_handler);
}
@OnClick(R.id.clear_app_data)
void clearAppDate(View view) {
App.Companion.deleteAppData();
}
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/GenreDetailsActivity.java b/app/src/main/java/code/name/monkey/retromusic/ui/activities/GenreDetailsActivity.java
deleted file mode 100644
index f7130704..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/GenreDetailsActivity.java
+++ /dev/null
@@ -1,226 +0,0 @@
-package code.name.monkey.retromusic.ui.activities;
-
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.ProgressBar;
-import android.widget.TextView;
-
-import com.afollestad.materialcab.MaterialCab;
-import com.google.android.material.appbar.AppBarLayout;
-import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
-
-import java.util.ArrayList;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.widget.Toolbar;
-import androidx.recyclerview.widget.DefaultItemAnimator;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import code.name.monkey.appthemehelper.ThemeStore;
-import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.helper.MusicPlayerRemote;
-import code.name.monkey.retromusic.helper.menu.GenreMenuHelper;
-import code.name.monkey.retromusic.interfaces.CabHolder;
-import code.name.monkey.retromusic.model.Genre;
-import code.name.monkey.retromusic.model.Song;
-import code.name.monkey.retromusic.mvp.contract.GenreDetailsContract;
-import code.name.monkey.retromusic.mvp.presenter.GenreDetailsPresenter;
-import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity;
-import code.name.monkey.retromusic.ui.adapter.song.SongAdapter;
-import code.name.monkey.retromusic.util.RetroColorUtil;
-import code.name.monkey.retromusic.util.ViewUtil;
-import code.name.monkey.retromusic.views.CollapsingFAB;
-
-/**
- * @author Hemanth S (h4h13).
- */
-
-public class GenreDetailsActivity extends AbsSlidingMusicPanelActivity implements GenreDetailsContract.GenreDetailsView, CabHolder {
- public static final String EXTRA_GENRE_ID = "extra_genre_id";
-
- @BindView(R.id.recycler_view)
- RecyclerView recyclerView;
-
- @BindView(R.id.toolbar)
- Toolbar toolbar;
-
- @BindView(android.R.id.empty)
- TextView empty;
-
- @BindView(R.id.action_shuffle)
- CollapsingFAB shuffleButton;
-
- @BindView(R.id.progress_bar)
- ProgressBar progressBar;
-
- @BindView(R.id.app_bar)
- AppBarLayout appBarLayout;
-
- @BindView(R.id.title)
- TextView title;
-
- private Genre genre;
- private GenreDetailsPresenter presenter;
- private SongAdapter songAdapter;
- private MaterialCab cab;
-
- private void checkIsEmpty() {
- empty.setVisibility(
- songAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE
- );
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setDrawUnderStatusBar();
- super.onCreate(savedInstanceState);
- ButterKnife.bind(this);
-
- setNavigationbarColorAuto();
- setTaskDescriptionColorAuto();
- toggleBottomNavigationView(true);
- setLightNavigationBar(true);
-
-
- genre = getIntent().getParcelableExtra(EXTRA_GENRE_ID);
- presenter = new GenreDetailsPresenter(this, genre.getId());
-
- setUpToolBar();
- setupRecyclerView();
- }
-
- @OnClick({R.id.action_shuffle})
- public void onViewClicked(View view) {
- switch (view.getId()) {
- case R.id.action_shuffle:
- MusicPlayerRemote.INSTANCE.openAndShuffleQueue(songAdapter.getDataSet(), true);
- break;
- }
- }
-
- private void setUpToolBar() {
- title.setText(genre.getName());
- title.setTextColor(ThemeStore.textColorPrimary(this));
-
- int primaryColor = ThemeStore.primaryColor(this);
- toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
- toolbar.setBackgroundColor(primaryColor);
- appBarLayout.setBackgroundColor(primaryColor);
- ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this));
- setTitle(null);
- setSupportActionBar(toolbar);
- shuffleButton.setColor(ThemeStore.accentColor(this));
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- presenter.subscribe();
- }
-
- @Override
- protected void onPause() {
- super.onPause();
- presenter.unsubscribe();
- }
-
- @Override
- protected View createContentView() {
- return wrapSlidingMusicPanel(R.layout.activity_playlist_detail);
- }
-
-
- @Override
- public void loading() {
-
- }
-
- @Override
- public void showEmptyView() {
-
- }
-
- @Override
- public void completed() {
-
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.menu_genre_detail, menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == android.R.id.home) {
- onBackPressed();
- }
- return GenreMenuHelper.INSTANCE.handleMenuClick(this, genre, item);
- }
-
- private void setupRecyclerView() {
- ViewUtil.setUpFastScrollRecyclerViewColor(this,
- ((FastScrollRecyclerView) recyclerView), ThemeStore.accentColor(this));
- songAdapter = new SongAdapter(this, new ArrayList<>(), R.layout.item_list, false, this);
- recyclerView.setItemAnimator(new DefaultItemAnimator());
- recyclerView.setLayoutManager(new LinearLayoutManager(this));
- recyclerView.setAdapter(songAdapter);
- recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
- @Override
- public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
- super.onScrolled(recyclerView, dx, dy);
- if (dy > 0) {
- shuffleButton.setShowTitle(false);
- } else if (dy < 0) {
- shuffleButton.setShowTitle(true);
- }
- }
- });
- songAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
- @Override
- public void onChanged() {
- super.onChanged();
- checkIsEmpty();
- }
- });
- }
-
- @Override
- public void showData(ArrayList songs) {
- songAdapter.swapDataSet(songs);
- }
-
- @NonNull
- @Override
- public MaterialCab openCab(final int menu, final MaterialCab.Callback callback) {
- if (cab != null && cab.isActive()) cab.finish();
- cab = new MaterialCab(this, R.id.cab_stub)
- .setMenu(menu)
- .setCloseDrawableRes(R.drawable.ic_close_white_24dp)
- .setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(this)))
- .start(callback);
- return cab;
- }
-
- @Override
- public void onBackPressed() {
- if (cab != null && cab.isActive()) cab.finish();
- else {
- recyclerView.stopScroll();
- super.onBackPressed();
- }
- }
-
- @Override
- public void onMediaStoreChanged() {
- super.onMediaStoreChanged();
- presenter.subscribe();
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/GenreDetailsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/GenreDetailsActivity.kt
new file mode 100644
index 00000000..b1178cc1
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/GenreDetailsActivity.kt
@@ -0,0 +1,174 @@
+package code.name.monkey.retromusic.ui.activities
+
+import android.os.Bundle
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import androidx.recyclerview.widget.DefaultItemAnimator
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import butterknife.ButterKnife
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.helper.menu.GenreMenuHelper
+import code.name.monkey.retromusic.interfaces.CabHolder
+import code.name.monkey.retromusic.model.Genre
+import code.name.monkey.retromusic.model.Song
+import code.name.monkey.retromusic.mvp.contract.GenreDetailsContract
+import code.name.monkey.retromusic.mvp.presenter.GenreDetailsPresenter
+import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity
+import code.name.monkey.retromusic.ui.adapter.song.SongAdapter
+import code.name.monkey.retromusic.util.RetroColorUtil
+import code.name.monkey.retromusic.util.ViewUtil
+import com.afollestad.materialcab.MaterialCab
+import kotlinx.android.synthetic.main.activity_playlist_detail.*
+import java.util.*
+
+/**
+ * @author Hemanth S (h4h13).
+ */
+
+class GenreDetailsActivity : AbsSlidingMusicPanelActivity(), GenreDetailsContract.GenreDetailsView, CabHolder {
+
+ private var genre: Genre? = null
+ private var presenter: GenreDetailsPresenter? = null
+ private var songAdapter: SongAdapter? = null
+ private var cab: MaterialCab? = null
+
+ private fun checkIsEmpty() {
+ empty!!.visibility = if (songAdapter!!.itemCount == 0) View.VISIBLE else View.GONE
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ setDrawUnderStatusBar()
+ super.onCreate(savedInstanceState)
+ ButterKnife.bind(this)
+
+ setStatusbarColorAuto()
+ setNavigationbarColorAuto()
+ setTaskDescriptionColorAuto()
+
+ toggleBottomNavigationView(true)
+ setLightNavigationBar(true)
+
+
+ genre = intent.extras!!.getParcelable(EXTRA_GENRE_ID)
+ presenter = GenreDetailsPresenter(this, genre!!.id)
+
+ setUpToolBar()
+ setupRecyclerView()
+ actionShuffle.setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(songAdapter!!.dataSet, true) }
+ }
+
+ private fun setUpToolBar() {
+ bannerTitle!!.text = genre!!.name
+ bannerTitle!!.setTextColor(ThemeStore.textColorPrimary(this))
+
+ val primaryColor = ThemeStore.primaryColor(this)
+ toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
+ toolbar.setBackgroundColor(primaryColor)
+ appBarLayout.setBackgroundColor(primaryColor)
+ ToolbarContentTintHelper.colorBackButton(toolbar!!, ThemeStore.accentColor(this))
+ title = null
+ setSupportActionBar(toolbar)
+ actionShuffle.setColor(ThemeStore.accentColor(this))
+ }
+
+ override fun onResume() {
+ super.onResume()
+ presenter!!.subscribe()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ presenter!!.unsubscribe()
+ }
+
+ override fun createContentView(): View {
+ return wrapSlidingMusicPanel(R.layout.activity_playlist_detail)
+ }
+
+
+ override fun loading() {
+
+ }
+
+ override fun showEmptyView() {
+
+ }
+
+ override fun completed() {
+
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(R.menu.menu_genre_detail, menu)
+ return super.onCreateOptionsMenu(menu)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (item.itemId == android.R.id.home) {
+ onBackPressed()
+ }
+ return GenreMenuHelper.handleMenuClick(this, genre!!, item)
+ }
+
+ private fun setupRecyclerView() {
+ ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView, ThemeStore.accentColor(this))
+ songAdapter = SongAdapter(this, ArrayList(), R.layout.item_list, false, this)
+ recyclerView.apply {
+ itemAnimator = DefaultItemAnimator()
+ layoutManager = LinearLayoutManager(this@GenreDetailsActivity)
+ adapter = songAdapter
+ }.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+ if (dy > 0) {
+ actionShuffle.setShowTitle(false)
+ } else if (dy < 0) {
+ actionShuffle.setShowTitle(true)
+ }
+ }
+ })
+ songAdapter!!.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
+ override fun onChanged() {
+ super.onChanged()
+ checkIsEmpty()
+ }
+ })
+ }
+
+ override fun showData(songs: ArrayList) {
+ songAdapter!!.swapDataSet(songs)
+ }
+
+ override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
+ if (cab != null && cab!!.isActive) cab!!.finish()
+ cab = MaterialCab(this, R.id.cab_stub)
+ .setMenu(menuRes)
+ .setCloseDrawableRes(R.drawable.ic_close_white_24dp)
+ .setBackgroundColor(RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(this)))
+ .start(callback)
+ return cab!!
+ }
+
+ override fun onBackPressed() {
+ if (cab != null && cab!!.isActive)
+ cab!!.finish()
+ else {
+ recyclerView!!.stopScroll()
+ super.onBackPressed()
+ }
+ }
+
+ override fun onMediaStoreChanged() {
+ super.onMediaStoreChanged()
+ presenter!!.subscribe()
+ }
+
+ companion object {
+ const val EXTRA_GENRE_ID = "extra_genre_id"
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/MainActivity.kt
index e875ca79..81f934b6 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/MainActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/MainActivity.kt
@@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.*
import android.content.pm.PackageManager
import android.os.Bundle
+import android.os.Handler
import android.preference.PreferenceManager
import android.provider.MediaStore
import android.util.Log
@@ -12,8 +13,11 @@ import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import butterknife.ButterKnife
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.appthemehelper.util.ATHUtil
+import code.name.monkey.appthemehelper.util.NavigationViewUtil
+import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.RetroApplication
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SearchQueryHelper
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
@@ -23,16 +27,18 @@ import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.ui.fragments.mainactivity.LibraryFragment
+import code.name.monkey.retromusic.ui.fragments.mainactivity.folders.FoldersFragment
import code.name.monkey.retromusic.ui.fragments.mainactivity.home.BannerHomeFragment
import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.MaterialDialog
-import com.google.android.material.bottomnavigation.BottomNavigationView
import io.reactivex.disposables.CompositeDisposable
+import kotlinx.android.synthetic.main.activity_main_drawer_layout.*
import java.util.*
-class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedPreferenceChangeListener, BottomNavigationView.OnNavigationItemSelectedListener {
- lateinit var currentFragment: MainActivityFragmentCallbacks
+class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
+
+ private lateinit var currentFragment: MainActivityFragmentCallbacks
private var blockRequestPermissions: Boolean = false
private val disposable = CompositeDisposable()
@@ -63,16 +69,23 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
super.onCreate(savedInstanceState)
ButterKnife.bind(this)
- getBottomNavigationView()!!.setOnNavigationItemSelectedListener(this)
+ getBottomNavigationView()!!.setOnNavigationItemSelectedListener {
+ PreferenceUtil.getInstance().lastPage = it.itemId
+ selectedFragment(it.itemId)
+ true
+ }
+
+ setUpDrawerLayout()
if (savedInstanceState == null) {
- selectedFragment(PreferenceUtil.getInstance().lastPage)
+ setMusicChooser(PreferenceUtil.getInstance().lastMusicChooser)
} else {
- restoreCurrentFragment()
+ restoreCurrentFragment();
}
+
checkShowChangelog()
- if (!RetroApplication.isProVersion && !PreferenceManager.getDefaultSharedPreferences(this).getBoolean("shown", false)) {
+ if (!App.isProVersion && !PreferenceManager.getDefaultSharedPreferences(this).getBoolean("shown", false)) {
showPromotionalOffer()
}
}
@@ -104,7 +117,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
intent.putExtra("expand", false)
}
}
-
}
override fun onDestroy() {
@@ -114,16 +126,12 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this)
}
- fun setCurrentFragment(fragment: Fragment, isStackAdd: Boolean, tag: String) {
- val fragmentTransaction = supportFragmentManager.beginTransaction()
- fragmentTransaction.replace(R.id.fragment_container, fragment, tag)
- if (isStackAdd) {
- fragmentTransaction.addToBackStack(tag)
- }
- fragmentTransaction.commit()
+ private fun setCurrentFragment(fragment: Fragment) {
+ supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment, null).commit()
currentFragment = fragment as MainActivityFragmentCallbacks
}
+
private fun restoreCurrentFragment() {
currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as MainActivityFragmentCallbacks
}
@@ -139,7 +147,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
if (intent.action != null && intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) {
val songs = SearchQueryHelper.getSongs(this, intent.extras!!)
-
if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
MusicPlayerRemote.openAndShuffleQueue(songs, true)
} else {
@@ -148,15 +155,14 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
handled = true
}
- if (uri != null && uri.toString().length > 0) {
+ if (uri != null && uri.toString().isNotEmpty()) {
MusicPlayerRemote.playFromUri(uri)
handled = true
} else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) {
val id = parseIdFromIntent(intent, "playlistId", "playlist").toInt()
if (id >= 0) {
val position = intent.getIntExtra("position", 0)
- val songs = ArrayList(
- PlaylistSongsLoader.getPlaylistSongList(this, id).blockingFirst())
+ val songs = ArrayList(PlaylistSongsLoader.getPlaylistSongList(this, id).blockingFirst())
MusicPlayerRemote.openQueue(songs, position, true)
handled = true
}
@@ -164,16 +170,14 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
val id = parseIdFromIntent(intent, "albumId", "album").toInt()
if (id >= 0) {
val position = intent.getIntExtra("position", 0)
- MusicPlayerRemote
- .openQueue(AlbumLoader.getAlbum(this, id).blockingFirst().songs!!, position, true)
+ MusicPlayerRemote.openQueue(AlbumLoader.getAlbum(this, id).blockingFirst().songs!!, position, true)
handled = true
}
} else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
val id = parseIdFromIntent(intent, "artistId", "artist").toInt()
if (id >= 0) {
val position = intent.getIntExtra("position", 0)
- MusicPlayerRemote
- .openQueue(ArtistLoader.getArtist(this, id).blockingFirst().songs, position, true)
+ MusicPlayerRemote.openQueue(ArtistLoader.getArtist(this, id).blockingFirst().songs, position, true)
handled = true
}
}
@@ -192,7 +196,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
} catch (e: NumberFormatException) {
Log.e(TAG, e.message)
}
-
}
}
return id
@@ -213,6 +216,10 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
}
override fun handleBackPress(): Boolean {
+ if (drawerLayout.isDrawerOpen(navigationView)) {
+ drawerLayout.closeDrawers()
+ return true
+ }
return super.handleBackPress() || currentFragment.handleBackPress()
}
@@ -257,10 +264,10 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
private fun showPromotionalOffer() {
MaterialDialog.Builder(this)
.positiveText("Buy")
- .onPositive { dialog, which -> startActivity(Intent(this@MainActivity, ProVersionActivity::class.java)) }
+ .onPositive { _, _ -> startActivity(Intent(this@MainActivity, ProVersionActivity::class.java)) }
.negativeText(android.R.string.cancel)
.customView(R.layout.dialog_promotional_offer, false)
- .dismissListener { dialog ->
+ .dismissListener {
PreferenceManager.getDefaultSharedPreferences(this@MainActivity)
.edit()
.putBoolean("shown", true)
@@ -269,19 +276,82 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
.show()
}
- override fun onNavigationItemSelected(menuItem: MenuItem): Boolean {
- PreferenceUtil.getInstance().lastPage = menuItem.itemId
- selectedFragment(menuItem.itemId)
- return true
- }
-
private fun selectedFragment(itemId: Int) {
when (itemId) {
- R.id.action_album, R.id.action_artist, R.id.action_playlist, R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId), false, LibraryFragment.TAG)
- R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), false, BannerHomeFragment.TAG)
+ R.id.action_album,
+ R.id.action_artist,
+ R.id.action_playlist,
+ R.id.action_song -> setCurrentFragment(LibraryFragment.newInstance(itemId))
}
}
+ private fun setUpNavigationView() {
+ val accentColor = ThemeStore.accentColor(this)
+ NavigationViewUtil.setItemIconColors(navigationView, ATHUtil.resolveColor(this, R.attr.iconColor, ThemeStore.textColorSecondary(this)), accentColor)
+ NavigationViewUtil.setItemTextColors(navigationView, ThemeStore.textColorPrimary(this), accentColor)
+
+ checkSetUpPro()
+ navigationView.setNavigationItemSelectedListener { menuItem ->
+ drawerLayout.closeDrawers()
+ when (menuItem.itemId) {
+ R.id.nav_library -> Handler().postDelayed({ setMusicChooser(LIBRARY) }, 200)
+ R.id.nav_home -> Handler().postDelayed({ setMusicChooser(HOME) }, 200)
+ R.id.nav_folders -> Handler().postDelayed({ setMusicChooser(FOLDERS) }, 200)
+ R.id.buy_pro -> Handler().postDelayed({ startActivityForResult(Intent(this@MainActivity, ProVersionActivity::class.java), PURCHASE_REQUEST) }, 200)
+ }
+ true
+ }
+ }
+
+ private fun setMusicChooser(key: Int) {
+ PreferenceUtil.getInstance().lastMusicChooser = key
+ when (key) {
+ LIBRARY -> {
+ navigationView.setCheckedItem(R.id.nav_library)
+ setCurrentFragment(LibraryFragment.newInstance())
+ }
+ FOLDERS -> {
+ navigationView.setCheckedItem(R.id.nav_folders)
+ setCurrentFragment(FoldersFragment.newInstance(this))
+ }
+ HOME -> {
+ navigationView.setCheckedItem(R.id.nav_home)
+ setCurrentFragment(BannerHomeFragment())
+ }
+ }
+ }
+
+
+ private fun checkSetUpPro() {
+ if (App.isProVersion) {
+ setUpPro()
+ }
+ }
+
+ private fun setUpPro() {
+ navigationView.menu.removeGroup(R.id.navigation_drawer_menu_category_buy_pro)
+ }
+
+ private fun setUpDrawerLayout() {
+ setUpNavigationView()
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (item.itemId == android.R.id.home) {
+ if (drawerLayout.isDrawerOpen(navigationView)) {
+ drawerLayout.closeDrawer(navigationView)
+ } else {
+ drawerLayout.openDrawer(navigationView)
+ }
+ return true
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+ private fun updateNavigationDrawerHeader() {
+
+ }
+
companion object {
const val APP_INTRO_REQUEST = 2323
const val LIBRARY = 1
@@ -290,5 +360,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
private const val TAG = "MainActivity"
private const val APP_USER_INFO_REQUEST = 9003
private const val REQUEST_CODE_THEME = 9002
+ private const val PURCHASE_REQUEST = 101
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlaylistDetailActivity.java b/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlaylistDetailActivity.java
deleted file mode 100644
index 724b3e51..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlaylistDetailActivity.java
+++ /dev/null
@@ -1,309 +0,0 @@
-package code.name.monkey.retromusic.ui.activities;
-
-import android.os.Bundle;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.widget.TextView;
-
-import com.afollestad.materialcab.MaterialCab;
-import com.google.android.material.appbar.AppBarLayout;
-import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
-import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
-import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
-import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
-import com.simplecityapps.recyclerview_fastscroll.views.FastScrollRecyclerView;
-
-import java.util.ArrayList;
-
-import androidx.annotation.NonNull;
-import androidx.appcompat.widget.Toolbar;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import code.name.monkey.appthemehelper.ThemeStore;
-import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.helper.MusicPlayerRemote;
-import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper;
-import code.name.monkey.retromusic.interfaces.CabHolder;
-import code.name.monkey.retromusic.loaders.PlaylistLoader;
-import code.name.monkey.retromusic.model.AbsCustomPlaylist;
-import code.name.monkey.retromusic.model.Playlist;
-import code.name.monkey.retromusic.model.Song;
-import code.name.monkey.retromusic.mvp.contract.PlaylistSongsContract;
-import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsPresenter;
-import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity;
-import code.name.monkey.retromusic.ui.adapter.song.OrderablePlaylistSongAdapter;
-import code.name.monkey.retromusic.ui.adapter.song.PlaylistSongAdapter;
-import code.name.monkey.retromusic.ui.adapter.song.SongAdapter;
-import code.name.monkey.retromusic.util.PlaylistsUtil;
-import code.name.monkey.retromusic.util.RetroColorUtil;
-import code.name.monkey.retromusic.util.ViewUtil;
-import code.name.monkey.retromusic.views.CollapsingFAB;
-
-public class PlaylistDetailActivity extends AbsSlidingMusicPanelActivity implements CabHolder,
- PlaylistSongsContract.PlaylistSongsView {
-
- @NonNull
- public static String EXTRA_PLAYLIST = "extra_playlist";
-
- @BindView(R.id.recycler_view)
- RecyclerView recyclerView;
-
- @BindView(R.id.toolbar)
- Toolbar toolbar;
-
- @BindView(android.R.id.empty)
- TextView empty;
-
- @BindView(R.id.action_shuffle)
- CollapsingFAB shuffleButton;
-
- @BindView(R.id.app_bar)
- AppBarLayout appBarLayout;
-
- @BindView(R.id.title)
- TextView title;
-
- private Playlist playlist;
- private MaterialCab cab;
- private SongAdapter adapter;
- private RecyclerView.Adapter wrappedAdapter;
- private RecyclerViewDragDropManager recyclerViewDragDropManager;
- private PlaylistSongsPresenter songsPresenter;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- setDrawUnderStatusBar();
- super.onCreate(savedInstanceState);
- ButterKnife.bind(this);
-
- setStatusbarColorAuto();
- setNavigationbarColorAuto();
- setTaskDescriptionColorAuto();
- setLightNavigationBar(true);
- toggleBottomNavigationView(true);
-
- playlist = getIntent().getExtras().getParcelable(EXTRA_PLAYLIST);
-
- if (playlist != null) {
- songsPresenter = new PlaylistSongsPresenter(this, playlist);
- }
-
- setUpToolBar();
- setUpRecyclerView();
- }
-
- @Override
- protected View createContentView() {
- return wrapSlidingMusicPanel(R.layout.activity_playlist_detail);
- }
-
- private void setUpRecyclerView() {
- ViewUtil.setUpFastScrollRecyclerViewColor(this, ((FastScrollRecyclerView) recyclerView),
- ThemeStore.accentColor(this));
- recyclerView.setLayoutManager(new LinearLayoutManager(this));
- if (playlist instanceof AbsCustomPlaylist) {
- adapter = new PlaylistSongAdapter(this, new ArrayList(), R.layout.item_list, false,
- this);
- recyclerView.setAdapter(adapter);
- } else {
- recyclerViewDragDropManager = new RecyclerViewDragDropManager();
- final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
- adapter = new OrderablePlaylistSongAdapter(this, new ArrayList<>(),
- R.layout.item_list, false, this, (fromPosition, toPosition) -> {
- if (PlaylistsUtil.moveItem(PlaylistDetailActivity.this, playlist.id, fromPosition, toPosition)) {
- Song song = adapter.getDataSet().remove(fromPosition);
- adapter.getDataSet().add(toPosition, song);
- adapter.notifyItemMoved(fromPosition, toPosition);
- }
- });
- wrappedAdapter = recyclerViewDragDropManager.createWrappedAdapter(adapter);
-
- recyclerView.setAdapter(wrappedAdapter);
- recyclerView.setItemAnimator(animator);
-
- recyclerViewDragDropManager.attachRecyclerView(recyclerView);
- }
- adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
- @Override
- public void onChanged() {
- super.onChanged();
- checkIsEmpty();
- }
- });
- recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
- @Override
- public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
- super.onScrolled(recyclerView, dx, dy);
- if (dy > 0) {
- shuffleButton.setShowTitle(false);
- } else if (dy < 0) {
- shuffleButton.setShowTitle(true);
- }
- }
- });
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- songsPresenter.subscribe();
- }
-
- private void setUpToolBar() {
- title.setText(playlist.name);
- title.setTextColor(ThemeStore.textColorPrimary(this));
- shuffleButton.setColor(ThemeStore.accentColor(this));
-
- int primaryColor = ThemeStore.primaryColor(this);
- toolbar.setBackgroundColor(primaryColor);
- appBarLayout.setBackgroundColor(primaryColor);
-
- setTitle(null);
- setSupportActionBar(toolbar);
- toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
-
- ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this));
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(playlist instanceof AbsCustomPlaylist ? R.menu.menu_smart_playlist_detail : R.menu.menu_playlist_detail, menu);
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(@NonNull MenuItem item) {
- int id = item.getItemId();
- switch (id) {
- case android.R.id.home:
- onBackPressed();
- return true;
- }
- return PlaylistMenuHelper.INSTANCE.handleMenuClick(this, playlist, item);
- }
-
- @NonNull
- @Override
- public MaterialCab openCab(final int menu, final MaterialCab.Callback callback) {
- if (cab != null && cab.isActive()) {
- cab.finish();
- }
- cab = new MaterialCab(this, R.id.cab_stub)
- .setMenu(menu)
- .setCloseDrawableRes(R.drawable.ic_close_white_24dp)
- .setBackgroundColor(
- RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(this)))
- .start(callback);
- return cab;
- }
-
- @Override
- public void onBackPressed() {
- if (cab != null && cab.isActive()) {
- cab.finish();
- } else {
- recyclerView.stopScroll();
- super.onBackPressed();
- }
- }
-
- @Override
- public void onMediaStoreChanged() {
- super.onMediaStoreChanged();
-
- if (!(playlist instanceof AbsCustomPlaylist)) {
- // Playlist deleted
- if (!PlaylistsUtil.doesPlaylistExist(this, playlist.id)) {
- finish();
- return;
- }
-
- // Playlist renamed
- final String playlistName = PlaylistsUtil.getNameForPlaylist(this, playlist.id);
- if (!playlistName.equals(playlist.name)) {
- playlist = PlaylistLoader.INSTANCE.getPlaylist(this, playlist.id).blockingFirst();
- setToolbarTitle(playlist.name);
- }
- }
- songsPresenter.subscribe();
- }
-
- private void setToolbarTitle(String title) {
- //noinspection ConstantConditions
- getSupportActionBar().setTitle(title);
- }
-
- private void checkIsEmpty() {
- empty.setVisibility(
- adapter.getItemCount() == 0 ? View.VISIBLE : View.GONE
- );
- }
-
- @Override
- public void onPause() {
- if (recyclerViewDragDropManager != null) {
- recyclerViewDragDropManager.cancelDrag();
- }
- super.onPause();
- songsPresenter.unsubscribe();
- }
-
- @Override
- public void onDestroy() {
- if (recyclerViewDragDropManager != null) {
- recyclerViewDragDropManager.release();
- recyclerViewDragDropManager = null;
- }
-
- if (recyclerView != null) {
- recyclerView.setItemAnimator(null);
- recyclerView.setAdapter(null);
- recyclerView = null;
- }
-
- if (wrappedAdapter != null) {
- WrapperAdapterUtils.releaseAll(wrappedAdapter);
- wrappedAdapter = null;
- }
- adapter = null;
-
- super.onDestroy();
- }
-
- @Override
- public void onPlayingMetaChanged() {
- super.onPlayingMetaChanged();
- songsPresenter.subscribe();
- }
-
- @Override
- public void loading() {
- }
-
- @Override
- public void showEmptyView() {
- empty.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void completed() {
- }
-
- @Override
- public void showData(ArrayList songs) {
- adapter.swapDataSet(songs);
- }
-
- @OnClick(R.id.action_shuffle)
- public void onViewClicked() {
- if (adapter.getDataSet().isEmpty()) {
- return;
- }
- MusicPlayerRemote.INSTANCE.openAndShuffleQueue(adapter.getDataSet(), true);
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlaylistDetailActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlaylistDetailActivity.kt
new file mode 100644
index 00000000..07ca6e0e
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/PlaylistDetailActivity.kt
@@ -0,0 +1,254 @@
+package code.name.monkey.retromusic.ui.activities
+
+import android.os.Bundle
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import butterknife.ButterKnife
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
+import code.name.monkey.retromusic.interfaces.CabHolder
+import code.name.monkey.retromusic.loaders.PlaylistLoader
+import code.name.monkey.retromusic.model.AbsCustomPlaylist
+import code.name.monkey.retromusic.model.Playlist
+import code.name.monkey.retromusic.model.Song
+import code.name.monkey.retromusic.mvp.contract.PlaylistSongsContract
+import code.name.monkey.retromusic.mvp.presenter.PlaylistSongsPresenter
+import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity
+import code.name.monkey.retromusic.ui.adapter.song.OrderablePlaylistSongAdapter
+import code.name.monkey.retromusic.ui.adapter.song.PlaylistSongAdapter
+import code.name.monkey.retromusic.ui.adapter.song.SongAdapter
+import code.name.monkey.retromusic.util.PlaylistsUtil
+import code.name.monkey.retromusic.util.RetroColorUtil
+import code.name.monkey.retromusic.util.ViewUtil
+import com.afollestad.materialcab.MaterialCab
+import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
+import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
+import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils
+import kotlinx.android.synthetic.main.activity_playlist_detail.*
+import java.util.*
+
+class PlaylistDetailActivity : AbsSlidingMusicPanelActivity(), CabHolder, PlaylistSongsContract.PlaylistSongsView {
+
+
+ private var playlist: Playlist? = null
+ private var cab: MaterialCab? = null
+ private lateinit var adapter: SongAdapter
+ private var wrappedAdapter: RecyclerView.Adapter<*>? = null
+ private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
+ private var songsPresenter: PlaylistSongsPresenter? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ setDrawUnderStatusBar()
+ super.onCreate(savedInstanceState)
+ ButterKnife.bind(this)
+
+ setStatusbarColorAuto()
+ setNavigationbarColorAuto()
+ setTaskDescriptionColorAuto()
+ setLightNavigationBar(true)
+ toggleBottomNavigationView(true)
+
+
+ playlist = intent.extras!!.getParcelable(EXTRA_PLAYLIST)
+ songsPresenter = PlaylistSongsPresenter(this, playlist!!)
+
+ setUpToolBar()
+ setUpRecyclerView()
+ }
+
+ override fun createContentView(): View {
+ return wrapSlidingMusicPanel(R.layout.activity_playlist_detail)
+ }
+
+ private fun setUpRecyclerView() {
+ ViewUtil.setUpFastScrollRecyclerViewColor(this, recyclerView, ThemeStore.accentColor(this))
+ recyclerView.layoutManager = LinearLayoutManager(this)
+ if (playlist is AbsCustomPlaylist) {
+ adapter = PlaylistSongAdapter(this, ArrayList(), R.layout.item_list, false, this)
+ recyclerView!!.adapter = adapter
+ } else {
+ recyclerViewDragDropManager = RecyclerViewDragDropManager()
+ val animator = RefactoredDefaultItemAnimator()
+ adapter = OrderablePlaylistSongAdapter(this, ArrayList(), R.layout.item_list, false, this,
+ object : OrderablePlaylistSongAdapter.OnMoveItemListener {
+ override fun onMoveItem(fromPosition: Int, toPosition: Int) {
+ if (PlaylistsUtil.moveItem(this@PlaylistDetailActivity, playlist!!.id, fromPosition, toPosition)) {
+ val song = adapter.dataSet.removeAt(fromPosition)
+ adapter.dataSet.add(toPosition, song)
+ adapter.notifyItemMoved(fromPosition, toPosition)
+ }
+ }
+ })
+ wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(adapter)
+
+ recyclerView.adapter = wrappedAdapter
+ recyclerView.itemAnimator = animator
+
+ recyclerViewDragDropManager!!.attachRecyclerView(recyclerView!!)
+ }
+ adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
+ override fun onChanged() {
+ super.onChanged()
+ checkIsEmpty()
+ }
+ })
+ recyclerView!!.addOnScrollListener(object : RecyclerView.OnScrollListener() {
+ override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
+ super.onScrolled(recyclerView, dx, dy)
+ if (dy > 0) {
+ actionShuffle.setShowTitle(false)
+ } else if (dy < 0) {
+ actionShuffle.setShowTitle(true)
+ }
+ }
+ })
+ actionShuffle.setOnClickListener {
+ if (adapter.dataSet.isEmpty()) {
+ return@setOnClickListener
+ }
+ MusicPlayerRemote.openAndShuffleQueue(adapter.dataSet, true)
+ }
+ }
+
+ override fun onResume() {
+ super.onResume()
+ songsPresenter!!.subscribe()
+ }
+
+ private fun setUpToolBar() {
+ bannerTitle.text = playlist!!.name
+ bannerTitle.setTextColor(ThemeStore.textColorPrimary(this))
+ actionShuffle.setColor(ThemeStore.accentColor(this))
+
+ val primaryColor = ThemeStore.primaryColor(this)
+ toolbar!!.setBackgroundColor(primaryColor)
+ appBarLayout!!.setBackgroundColor(primaryColor)
+
+ title = null
+ setSupportActionBar(toolbar)
+ toolbar!!.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp)
+
+ ToolbarContentTintHelper.colorBackButton(toolbar!!, ThemeStore.accentColor(this))
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ menuInflater.inflate(if (playlist is AbsCustomPlaylist) R.menu.menu_smart_playlist_detail else R.menu.menu_playlist_detail, menu)
+ return super.onCreateOptionsMenu(menu)
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ val id = item.itemId
+ when (id) {
+ android.R.id.home -> {
+ onBackPressed()
+ return true
+ }
+ }
+ return PlaylistMenuHelper.handleMenuClick(this, playlist!!, item)
+ }
+
+ override fun openCab(menuRes: Int, callback: MaterialCab.Callback): MaterialCab {
+ if (cab != null && cab!!.isActive) {
+ cab!!.finish()
+ }
+ cab = MaterialCab(this, R.id.cab_stub)
+ .setMenu(menuRes)
+ .setCloseDrawableRes(R.drawable.ic_close_white_24dp)
+ .setBackgroundColor(
+ RetroColorUtil.shiftBackgroundColorForLightText(ThemeStore.primaryColor(this)))
+ .start(callback)
+ return cab!!
+ }
+
+ override fun onBackPressed() {
+ if (cab != null && cab!!.isActive) {
+ cab!!.finish()
+ } else {
+ recyclerView!!.stopScroll()
+ super.onBackPressed()
+ }
+ }
+
+ override fun onMediaStoreChanged() {
+ super.onMediaStoreChanged()
+
+ if (playlist !is AbsCustomPlaylist) {
+ // Playlist deleted
+ if (!PlaylistsUtil.doesPlaylistExist(this, playlist!!.id)) {
+ finish()
+ return
+ }
+
+ // Playlist renamed
+ val playlistName = PlaylistsUtil.getNameForPlaylist(this, playlist!!.id.toLong())
+ if (playlistName != playlist!!.name) {
+ playlist = PlaylistLoader.getPlaylist(this, playlist!!.id).blockingFirst()
+ setToolbarTitle(playlist!!.name)
+ }
+ }
+ songsPresenter!!.subscribe()
+ }
+
+ private fun setToolbarTitle(title: String) {
+
+ supportActionBar!!.title = title
+ }
+
+ private fun checkIsEmpty() {
+ empty.visibility = if (adapter.itemCount == 0) View.VISIBLE else View.GONE
+ }
+
+ public override fun onPause() {
+ if (recyclerViewDragDropManager != null) {
+ recyclerViewDragDropManager!!.cancelDrag()
+ }
+ super.onPause()
+ songsPresenter!!.unsubscribe()
+ }
+
+ override fun onDestroy() {
+ if (recyclerViewDragDropManager != null) {
+ recyclerViewDragDropManager!!.release()
+ recyclerViewDragDropManager = null
+ }
+
+ if (recyclerView != null) {
+ recyclerView!!.itemAnimator = null
+ recyclerView!!.adapter = null
+ }
+
+ if (wrappedAdapter != null) {
+ WrapperAdapterUtils.releaseAll(wrappedAdapter)
+ wrappedAdapter = null
+ }
+ super.onDestroy()
+ }
+
+ override fun onPlayingMetaChanged() {
+ super.onPlayingMetaChanged()
+ songsPresenter!!.subscribe()
+ }
+
+ override fun loading() {}
+
+ override fun showEmptyView() {
+ empty!!.visibility = View.VISIBLE
+ }
+
+ override fun completed() {}
+
+ override fun showData(songs: ArrayList) {
+ adapter.swapDataSet(songs)
+ }
+
+ companion object {
+
+ var EXTRA_PLAYLIST = "extra_playlist"
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/ProVersionActivity.java b/app/src/main/java/code/name/monkey/retromusic/ui/activities/ProVersionActivity.java
index e2a8ea95..cd425bd6 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/ProVersionActivity.java
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/ProVersionActivity.java
@@ -27,7 +27,7 @@ import code.name.monkey.appthemehelper.util.MaterialUtil;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.BuildConfig;
import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.RetroApplication;
+import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
/**
@@ -106,7 +106,7 @@ public class ProVersionActivity extends AbsBaseActivity implements
}
break;
case R.id.purchase_button:
- billingProcessor.purchase(ProVersionActivity.this, RetroApplication.PRO_VERSION_PRODUCT_ID);
+ billingProcessor.purchase(ProVersionActivity.this, App.PRO_VERSION_PRODUCT_ID);
break;
}
}
@@ -119,7 +119,7 @@ public class ProVersionActivity extends AbsBaseActivity implements
@Override
public void onPurchaseHistoryRestored() {
- if (RetroApplication.Companion.isProVersion()) {
+ if (App.Companion.isProVersion()) {
Toast.makeText(this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG)
.show();
setResult(RESULT_OK);
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/SettingsActivity.java b/app/src/main/java/code/name/monkey/retromusic/ui/activities/SettingsActivity.java
deleted file mode 100755
index b0e912ab..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/SettingsActivity.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package code.name.monkey.retromusic.ui.activities;
-
-import android.content.SharedPreferences;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.MenuItem;
-import android.widget.FrameLayout;
-import android.widget.TextView;
-
-import com.afollestad.materialdialogs.color.ColorChooserDialog;
-import com.google.android.material.appbar.AppBarLayout;
-
-import androidx.annotation.ColorInt;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.appcompat.widget.Toolbar;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentTransaction;
-import androidx.transition.TransitionManager;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import code.name.monkey.appthemehelper.ThemeStore;
-import code.name.monkey.appthemehelper.util.ColorUtil;
-import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
-import code.name.monkey.retromusic.ui.fragments.settings.MainSettingsFragment;
-import code.name.monkey.retromusic.util.PreferenceUtil;
-
-public class SettingsActivity extends AbsBaseActivity implements ColorChooserDialog.ColorCallback, SharedPreferences.OnSharedPreferenceChangeListener {
-
- private static final String TAG = "SettingsActivity";
-
- @BindView(R.id.toolbar)
- Toolbar toolbar;
-
- @BindView(R.id.app_bar)
- AppBarLayout appBarLayout;
-
- @BindView(R.id.title)
- TextView title;
-
- @BindView(R.id.detail_content_frame)
- @Nullable
- FrameLayout detailsFrame;
-
- private FragmentManager fragmentManager = getSupportFragmentManager();
-
- @Override
- public void onColorSelection(@NonNull ColorChooserDialog dialog, @ColorInt int selectedColor) {
- switch (dialog.getTitle()) {
- case R.string.primary_color:
- int theme = ColorUtil.isColorLight(selectedColor) ?
- PreferenceUtil.getThemeResFromPrefValue("light") :
- PreferenceUtil.getThemeResFromPrefValue("dark");
-
- ThemeStore.editTheme(this).activityTheme(theme).primaryColor(selectedColor).commit();
- break;
- case R.string.accent_color:
- ThemeStore.editTheme(this).accentColor(selectedColor).commit();
- break;
- }
-
- recreate();
- }
-
- @Override
- public void onColorChooserDismissed(@NonNull ColorChooserDialog dialog) {
-
- }
-
- @Override
- protected void onCreate(@Nullable Bundle bundle) {
- super.onCreate(bundle);
- setContentView(R.layout.activity_settings);
- ButterKnife.bind(this);
-
- setStatusbarColorAuto();
- setNavigationbarColorAuto();
-
- setLightNavigationBar(true);
-
- setupToolbar();
-
- if (bundle == null) {
- fragmentManager.beginTransaction().replace(R.id.content_frame, new MainSettingsFragment())
- .commit();
- }
- }
-
- private void setupToolbar() {
- toolbar.setBackgroundColor(ThemeStore.primaryColor(this));
- appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this));
- setSupportActionBar(toolbar);
- setTitle(null);
- toolbar.setNavigationOnClickListener(v -> onBackPressed());
- title.setTextColor(ThemeStore.textColorPrimary(this));
- ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this));
- }
-
- public void setupFragment(Fragment fragment, @StringRes int titleName) {
- FragmentTransaction fragmentTransaction = fragmentManager
- .beginTransaction()
- .setCustomAnimations(R.anim.sliding_in_left, R.anim.sliding_out_right, android.R.anim.slide_in_left, android.R.anim.slide_out_right);
-
- title.setText(titleName);
-
- if (detailsFrame == null) {
- fragmentTransaction.replace(R.id.content_frame, fragment, fragment.getTag());
- fragmentTransaction.addToBackStack(null);
- fragmentTransaction.commit();
- } else {
- fragmentTransaction.replace(R.id.detail_content_frame, fragment, fragment.getTag());
- fragmentTransaction.commit();
- }
- }
-
- @Override
- public void onBackPressed() {
- if (fragmentManager.getBackStackEntryCount() == 0) {
- super.onBackPressed();
- } else {
- title.setText(R.string.action_settings);
- fragmentManager.popBackStack();
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == android.R.id.home) {
- onBackPressed();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- public void addAppbarLayoutElevation(float v) {
- TransitionManager.beginDelayedTransition(appBarLayout);
- appBarLayout.setElevation(v);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this);
- }
-
- @Override
- public void onResume() {
- super.onResume();
- PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this);
- }
-
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- Log.i(TAG, "onSharedPreferenceChanged: ");
- if (key.equals(PreferenceUtil.PROFILE_IMAGE_PATH)) {
- recreate();
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/SettingsActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/SettingsActivity.kt
new file mode 100755
index 00000000..e0fe1e00
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/SettingsActivity.kt
@@ -0,0 +1,124 @@
+package code.name.monkey.retromusic.ui.activities
+
+import android.content.SharedPreferences
+import android.os.Bundle
+import android.view.MenuItem
+import androidx.annotation.ColorInt
+import androidx.annotation.StringRes
+import androidx.fragment.app.Fragment
+import butterknife.ButterKnife
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.appthemehelper.util.ColorUtil
+import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity
+import code.name.monkey.retromusic.ui.fragments.settings.MainSettingsFragment
+import code.name.monkey.retromusic.util.PreferenceUtil
+import com.afollestad.materialdialogs.color.ColorChooserDialog
+import kotlinx.android.synthetic.main.activity_settings.*
+
+class SettingsActivity : AbsBaseActivity(), ColorChooserDialog.ColorCallback, SharedPreferences.OnSharedPreferenceChangeListener {
+
+ private val fragmentManager = supportFragmentManager
+
+ override fun onColorSelection(dialog: ColorChooserDialog, @ColorInt selectedColor: Int) {
+ when (dialog.title) {
+ R.string.primary_color -> {
+ val theme = if (ColorUtil.isColorLight(selectedColor))
+ PreferenceUtil.getThemeResFromPrefValue("light")
+ else
+ PreferenceUtil.getThemeResFromPrefValue("dark")
+
+ ThemeStore.editTheme(this).activityTheme(theme).primaryColor(selectedColor).commit()
+ }
+ R.string.accent_color -> ThemeStore.editTheme(this).accentColor(selectedColor).commit()
+ }
+ recreate()
+ }
+
+ override fun onColorChooserDismissed(dialog: ColorChooserDialog) {
+
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_settings)
+ ButterKnife.bind(this)
+
+ setStatusbarColorAuto()
+ setNavigationbarColorAuto()
+
+ setLightNavigationBar(true)
+
+ setupToolbar()
+
+ if (savedInstanceState == null) {
+ fragmentManager.beginTransaction().replace(R.id.contentFrame, MainSettingsFragment())
+ .commit()
+ }
+ }
+
+ private fun setupToolbar() {
+ setSupportActionBar(toolbar)
+ title = null
+ toolbar.setBackgroundColor(ThemeStore.primaryColor(this))
+ appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
+ toolbar.setNavigationOnClickListener { onBackPressed() }
+ settingsTitle.setTextColor(ThemeStore.textColorPrimary(this))
+ ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
+ }
+
+ fun setupFragment(fragment: Fragment, @StringRes titleName: Int) {
+ val fragmentTransaction = fragmentManager
+ .beginTransaction()
+ .setCustomAnimations(R.anim.sliding_in_left, R.anim.sliding_out_right, android.R.anim.slide_in_left, android.R.anim.slide_out_right)
+
+ settingsTitle.setText(titleName)
+
+ if (detailContentFrame == null) {
+ fragmentTransaction.replace(R.id.contentFrame, fragment, fragment.tag)
+ fragmentTransaction.addToBackStack(null)
+ fragmentTransaction.commit()
+ } else {
+ fragmentTransaction.replace(R.id.detailContentFrame, fragment, fragment.tag)
+ fragmentTransaction.commit()
+ }
+ }
+
+ override fun onBackPressed() {
+ if (fragmentManager.backStackEntryCount == 0) {
+ super.onBackPressed()
+ } else {
+ settingsTitle.setText(R.string.action_settings)
+ fragmentManager.popBackStack()
+ }
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (item.itemId == android.R.id.home) {
+ onBackPressed()
+ return true
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+ public override fun onPause() {
+ super.onPause()
+ PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this)
+ }
+
+ public override fun onResume() {
+ super.onResume()
+ PreferenceUtil.getInstance().registerOnSharedPreferenceChangedListener(this)
+ }
+
+ override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
+ if (key == PreferenceUtil.PROFILE_IMAGE_PATH) {
+ recreate()
+ }
+ }
+
+ companion object {
+ const val TAG: String = "SettingsActivity"
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/WhatsNewActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/WhatsNewActivity.kt
index f70c5e94..d8a6d492 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/WhatsNewActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/WhatsNewActivity.kt
@@ -46,7 +46,7 @@ class WhatsNewActivity : AbsBaseActivity() {
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
setSupportActionBar(toolbar)
title = null
- toolbar.setNavigationOnClickListener({ v -> onBackPressed() })
+ toolbar.setNavigationOnClickListener { onBackPressed() }
whatNewtitle.setTextColor(ThemeStore.textColorPrimary(this))
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsBaseActivity.java b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsBaseActivity.java
deleted file mode 100644
index 1c679cff..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsBaseActivity.java
+++ /dev/null
@@ -1,159 +0,0 @@
-package code.name.monkey.retromusic.ui.activities.base;
-
-import android.Manifest;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.media.AudioManager;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.google.android.material.snackbar.Snackbar;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.app.ActivityCompat;
-import androidx.core.view.ViewCompat;
-import code.name.monkey.appthemehelper.ThemeStore;
-import code.name.monkey.retromusic.R;
-import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;
-
-
-public abstract class AbsBaseActivity extends AbsThemeActivity {
-
- public static final int PERMISSION_REQUEST = 100;
- private boolean hadPermissions;
- private String[] permissions;
- private String permissionDeniedMessage;
-
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setVolumeControlStream(AudioManager.STREAM_MUSIC);
-
- permissions = getPermissionsToRequest();
- hadPermissions = hasPermissions();
-
- setPermissionDeniedMessage(null);
- }
-
- @Override
- protected void onPostCreate(@Nullable Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
- if (!hasPermissions()) {
- requestPermissions();
- }
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- final boolean hasPermissions = hasPermissions();
- if (hasPermissions != hadPermissions) {
- hadPermissions = hasPermissions;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- onHasPermissionsChanged(hasPermissions);
- }
- }
- }
-
- protected void onHasPermissionsChanged(boolean hasPermissions) {
- // implemented by sub classes
- }
-
- @Override
- public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
- if (event.getKeyCode() == KeyEvent.KEYCODE_MENU && event.getAction() == KeyEvent.ACTION_UP) {
- showOverflowMenu();
- return true;
- }
- return super.dispatchKeyEvent(event);
- }
-
- protected void showOverflowMenu() {
-
- }
-
- @Override
- protected void attachBaseContext(Context newBase) {
- super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
- }
-
- @Nullable
- protected String[] getPermissionsToRequest() {
- return null;
- }
-
- protected View getSnackBarContainer() {
- return getWindow().getDecorView();
- }
-
- private String getPermissionDeniedMessage() {
- return permissionDeniedMessage == null ? getString(R.string.permissions_denied)
- : permissionDeniedMessage;
- }
-
- protected void setPermissionDeniedMessage(String message) {
- permissionDeniedMessage = message;
- }
-
- protected void requestPermissions() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && permissions != null) {
- requestPermissions(permissions, PERMISSION_REQUEST);
- }
- }
-
- protected boolean hasPermissions() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && permissions != null) {
- for (String permission : permissions) {
- if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
- return false;
- }
- }
- }
- return true;
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
- @NonNull int[] grantResults) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- if (requestCode == PERMISSION_REQUEST) {
- for (int grantResult : grantResults) {
- if (grantResult != PackageManager.PERMISSION_GRANTED) {
- if (ActivityCompat.shouldShowRequestPermissionRationale(AbsBaseActivity.this,
- Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
- //User has deny from permission dialog
- Snackbar.make(getSnackBarContainer(), getPermissionDeniedMessage(),
- Snackbar.LENGTH_INDEFINITE)
- .setAction(R.string.action_grant, view -> requestPermissions())
- .setActionTextColor(ThemeStore.accentColor(this))
- .show();
- } else {
- // User has deny permission and checked never show permission dialog so you can redirect to Application settings page
- Snackbar.make(getSnackBarContainer(), getPermissionDeniedMessage(),
- Snackbar.LENGTH_INDEFINITE)
- .setAction(R.string.action_settings, view -> {
- Intent intent = new Intent();
- intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
- Uri uri = Uri.fromParts("package", AbsBaseActivity.this.getPackageName(), null);
- intent.setData(uri);
- startActivity(intent);
- })
- .setActionTextColor(ThemeStore.accentColor(this))
- .show();
- }
- return;
- }
- }
- hadPermissions = true;
- onHasPermissionsChanged(true);
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsBaseActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsBaseActivity.kt
index 25850c50..5bbafb05 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsBaseActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsBaseActivity.kt
@@ -1,7 +1,6 @@
package code.name.monkey.retromusic.ui.activities.base
import android.Manifest
-import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.media.AudioManager
@@ -15,17 +14,16 @@ import androidx.core.app.ActivityCompat
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R
import com.google.android.material.snackbar.Snackbar
-import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper
abstract class AbsBaseActivity : AbsThemeActivity() {
private var hadPermissions: Boolean = false
- private var permissions: Array? = null
+ private lateinit var permissions: Array
private var permissionDeniedMessage: String? = null
- open fun getPermissionsToRequest(): Array? {
- return null
+ open fun getPermissionsToRequest(): Array {
+ return arrayOf()
}
protected fun setPermissionDeniedMessage(message: String) {
@@ -82,20 +80,16 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
protected fun showOverflowMenu() {
}
-
- override fun attachBaseContext(newBase: Context) {
- super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase))
- }
-
+
protected open fun requestPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- requestPermissions(permissions!!, PERMISSION_REQUEST)
+ requestPermissions(permissions, PERMISSION_REQUEST)
}
}
protected fun hasPermissions(): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- for (permission in permissions!!) {
+ for (permission in permissions) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
return false
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsMusicServiceActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsMusicServiceActivity.kt
index 086c9786..e22fb801 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsMusicServiceActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsMusicServiceActivity.kt
@@ -138,7 +138,7 @@ abstract class AbsMusicServiceActivity : AbsCastActivity(), MusicServiceEventLis
}
- override fun getPermissionsToRequest(): Array? {
+ override fun getPermissionsToRequest(): Array {
return arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
}
@@ -163,6 +163,6 @@ abstract class AbsMusicServiceActivity : AbsCastActivity(), MusicServiceEventLis
}
companion object {
- val TAG = AbsMusicServiceActivity::class.java.simpleName
+ val TAG: String = AbsMusicServiceActivity::class.java.simpleName
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsSlidingMusicPanelActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsSlidingMusicPanelActivity.kt
index d41255e7..6035d437 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsSlidingMusicPanelActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsSlidingMusicPanelActivity.kt
@@ -21,6 +21,10 @@ import code.name.monkey.retromusic.ui.fragments.NowPlayingScreen
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.ui.fragments.player.adaptive.AdaptiveFragment
import code.name.monkey.retromusic.ui.fragments.player.blur.BlurPlayerFragment
+import code.name.monkey.retromusic.ui.fragments.player.card.CardFragment
+import code.name.monkey.retromusic.ui.fragments.player.cardblur.CardBlurFragment
+import code.name.monkey.retromusic.ui.fragments.player.fit.FitFragment
+import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.views.BottomNavigationBarTinted
import com.google.android.material.bottomnavigation.BottomNavigationView
@@ -58,7 +62,7 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
slidingUpPanelLayout = findViewById(R.id.sliding_layout);
bottomNavigationView = findViewById(R.id.bottom_navigation);
- choosFragmentForTheme()
+ chooseFragmentForTheme()
setupSlidingUpPanel()
}
@@ -207,22 +211,23 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
miniPlayerFragment!!.view!!.visibility = if (alpha == 0f) View.GONE else View.VISIBLE
}
- private fun choosFragmentForTheme() {
+ private fun chooseFragmentForTheme() {
currentNowPlayingScreen = PreferenceUtil.getInstance().nowPlayingScreen
- val fragment: Fragment // must implement AbsPlayerFragment
- when (currentNowPlayingScreen) {
- NowPlayingScreen.BLUR -> fragment = BlurPlayerFragment()
- NowPlayingScreen.ADAPTIVE -> fragment = AdaptiveFragment()
- else -> fragment = AdaptiveFragment()
- }
+ val fragment: Fragment = when (currentNowPlayingScreen) {
+ NowPlayingScreen.BLUR -> BlurPlayerFragment()
+ NowPlayingScreen.ADAPTIVE -> AdaptiveFragment()
+ NowPlayingScreen.NORMAL -> PlayerFragment()
+ NowPlayingScreen.CARD -> CardFragment()
+ NowPlayingScreen.BLUR_CARD -> CardBlurFragment()
+ NowPlayingScreen.FIT -> FitFragment()
+ else -> PlayerFragment()
+ } // must implement AbsPlayerFragment
supportFragmentManager.beginTransaction().replace(R.id.player_fragment_container, fragment).commit()
supportFragmentManager.executePendingTransactions()
- playerFragment = supportFragmentManager.findFragmentById(R.id.player_fragment_container) as AbsPlayerFragment?
- miniPlayerFragment = supportFragmentManager.findFragmentById(R.id.mini_player_fragment) as MiniPlayerFragment?
-
-
+ playerFragment = supportFragmentManager.findFragmentById(R.id.player_fragment_container) as AbsPlayerFragment
+ miniPlayerFragment = supportFragmentManager.findFragmentById(R.id.mini_player_fragment) as MiniPlayerFragment
miniPlayerFragment!!.view!!.setOnClickListener { expandPanel() }
}
@@ -296,6 +301,6 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
companion object {
- val TAG = AbsSlidingMusicPanelActivity::class.java.simpleName
+ val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
}
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsThemeActivity.kt b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsThemeActivity.kt
index a88a03e6..fb99ef1b 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsThemeActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/activities/base/AbsThemeActivity.kt
@@ -96,15 +96,16 @@ abstract class AbsThemeActivity : ATHActivity(), Runnable {
if (VersionUtils.hasKitKat()) {
val statusBar = window.decorView.rootView.findViewById(R.id.status_bar)
if (statusBar != null) {
- if (VersionUtils.hasMarshmallow()) {
- window.statusBarColor = color
- } else if (VersionUtils.hasLollipop()) {
- statusBar.setBackgroundColor(ColorUtil.darkenColor(color))
- } else {
- statusBar.setBackgroundColor(color)
+ when {
+ VersionUtils.hasMarshmallow() -> window.statusBarColor = color
+ VersionUtils.hasLollipop() -> statusBar.setBackgroundColor(ColorUtil.darkenColor(color))
+ else -> statusBar.setBackgroundColor(color)
}
} else if (Build.VERSION.SDK_INT >= 21) {
- window.statusBarColor = ColorUtil.darkenColor(color)
+ when {
+ VersionUtils.hasMarshmallow() -> window.statusBarColor = color
+ else -> window.statusBarColor = ColorUtil.darkenColor(color)
+ }
}
}
setLightStatusbarAuto(color)
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/adapter/CollageSongAdapter.java b/app/src/main/java/code/name/monkey/retromusic/ui/adapter/CollageSongAdapter.java
index 4e955f2c..166f7f65 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/adapter/CollageSongAdapter.java
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/adapter/CollageSongAdapter.java
@@ -70,8 +70,7 @@ public class CollageSongAdapter extends RecyclerView.Adapter imageViews;
@@ -80,14 +79,12 @@ public class CollageSongAdapter extends RecyclerView.Adapter {
- MusicPlayerRemote.INSTANCE.openQueue(dataSet, 0, true);
- });
- view.setBackgroundColor(color);
- view.setTextColor(MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color)));
+ //ButterKnife.bind(this, itemView);
+ //Context context = itemView.getContext();
+ //int color = ThemeStore.accentColor(context);
+ //view.setOnClickListener(v -> MusicPlayerRemote.INSTANCE.openQueue(dataSet, 0, true));
+ //view.setBackgroundColor(color);
+ //view.setTextColor(MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color)));
}
void bindSongs() {
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/adapter/song/AbsOffsetSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/ui/adapter/song/AbsOffsetSongAdapter.kt
index 4329ea2b..92e25f58 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/adapter/song/AbsOffsetSongAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/adapter/song/AbsOffsetSongAdapter.kt
@@ -61,7 +61,7 @@ abstract class AbsOffsetSongAdapter : SongAdapter {
override// could also return null, just to be safe return empty song
val song: Song
- get() = if (itemViewType == OFFSET_ITEM) Song.EMPTY_SONG else dataSet[adapterPosition - 1]
+ get() = if (itemViewType == OFFSET_ITEM) Song.emptySong else dataSet[adapterPosition - 1]
override fun onClick(v: View?) {
if (isInQuickSelectMode && itemViewType != OFFSET_ITEM) {
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/adapter/song/OrderablePlaylistSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/ui/adapter/song/OrderablePlaylistSongAdapter.kt
index a55a548f..8889c516 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/adapter/song/OrderablePlaylistSongAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/adapter/song/OrderablePlaylistSongAdapter.kt
@@ -36,7 +36,7 @@ class OrderablePlaylistSongAdapter(activity: AppCompatActivity,
positionFinal--
var long: Long = 0
- if (position < 0) {
+ if (positionFinal < 0) {
long = -2
} else {
if (dataSet[positionFinal] is PlaylistSong) {
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/MiniPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/MiniPlayerFragment.kt
index d627fd68..34d90346 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/MiniPlayerFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/MiniPlayerFragment.kt
@@ -10,7 +10,6 @@ import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import android.view.*
import android.view.animation.DecelerateInterpolator
-import butterknife.OnClick
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote
@@ -76,7 +75,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
private fun updateSongTitle() {
val builder = SpannableStringBuilder()
- val song = MusicPlayerRemote.currentSong ?: return
+ val song = MusicPlayerRemote.currentSong
val title = SpannableString(song.title)
title.setSpan(ForegroundColorSpan(ThemeStore.textColorPrimary(context!!)), 0, title.length, 0)
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/NowPlayingScreen.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/NowPlayingScreen.java
index 59f4288e..5b74e577 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/NowPlayingScreen.java
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/NowPlayingScreen.java
@@ -6,9 +6,19 @@ import code.name.monkey.retromusic.R;
public enum NowPlayingScreen {
-
+ NORMAL(R.string.normal, R.drawable.np_normal, 0),
+ FLAT(R.string.flat, R.drawable.np_flat, 1),
+ //FULL(R.string.full, R.drawable.np_full, 2),
+ //PLAIN(R.string.plain, R.drawable.np_plain, 3),
+ BLUR(R.string.blur, R.drawable.np_blur, 4),
+ //COLOR(R.string.color, R.drawable.np_color, 5),
+ CARD(R.string.card, R.drawable.np_card, 6),
+ //TINY(R.string.tiny, R.drawable.np_tiny, 7),
+ //SIMPLE(R.string.simple, R.drawable.np_simple, 8),
+ BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
ADAPTIVE(R.string.adaptive, R.drawable.np_adaptive, 10),
- BLUR(R.string.blur, R.drawable.np_blur, 4);
+ //MATERIAL(R.string.material, R.drawable.np_material, 11),
+ FIT(R.string.fit, R.drawable.np_adaptive, 12);
@StringRes
public final int titleRes;
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/PlayingQueueFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/PlayingQueueFragment.java
deleted file mode 100644
index 6f6865d7..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/PlayingQueueFragment.java
+++ /dev/null
@@ -1,148 +0,0 @@
-package code.name.monkey.retromusic.ui.fragments;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.h6ah4i.android.widget.advrecyclerview.animator.GeneralItemAnimator;
-import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator;
-import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager;
-import com.h6ah4i.android.widget.advrecyclerview.utils.WrapperAdapterUtils;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.appcompat.app.AppCompatActivity;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.Unbinder;
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.helper.MusicPlayerRemote;
-import code.name.monkey.retromusic.ui.adapter.song.PlayingQueueAdapter;
-import code.name.monkey.retromusic.ui.fragments.base.AbsMusicServiceFragment;
-import code.name.monkey.retromusic.views.CollapsingFAB;
-
-public class PlayingQueueFragment extends AbsMusicServiceFragment {
-
- @BindView(R.id.recycler_view)
- RecyclerView mRecyclerView;
-
-
- Unbinder unbinder;
-
- private RecyclerView.Adapter mWrappedAdapter;
- private RecyclerViewDragDropManager mRecyclerViewDragDropManager;
- private PlayingQueueAdapter mPlayingQueueAdapter;
- private LinearLayoutManager mLayoutManager;
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_main_activity_recycler_view, container, false);
- unbinder = ButterKnife.bind(this, view);
- return view;
- }
-
- @Override
- public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- setUpRecyclerView();
- }
-
- private void setUpRecyclerView() {
- mRecyclerViewDragDropManager = new RecyclerViewDragDropManager();
- final GeneralItemAnimator animator = new RefactoredDefaultItemAnimator();
-
- mPlayingQueueAdapter = new PlayingQueueAdapter(
- (AppCompatActivity) getActivity(),
- MusicPlayerRemote.INSTANCE.getPlayingQueue(),
- MusicPlayerRemote.INSTANCE.getPosition(),
- R.layout.item_queue);
- mWrappedAdapter = mRecyclerViewDragDropManager.createWrappedAdapter(mPlayingQueueAdapter);
-
- mLayoutManager = new LinearLayoutManager(getContext());
-
- mRecyclerView.setLayoutManager(mLayoutManager);
- mRecyclerView.setAdapter(mWrappedAdapter);
- mRecyclerView.setItemAnimator(animator);
- mRecyclerViewDragDropManager.attachRecyclerView(mRecyclerView);
- mLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.INSTANCE.getPosition() + 1, 0);
-
- }
-
- @Override
- public void onQueueChanged() {
- updateQueue();
- updateCurrentSong();
- }
-
- @Override
- public void onMediaStoreChanged() {
- updateQueue();
- updateCurrentSong();
- }
-
- @SuppressWarnings("ConstantConditions")
- private void updateCurrentSong() {
- }
-
- @Override
- public void onPlayingMetaChanged() {
- //updateCurrentSong();
- //updateIsFavorite();
- updateQueuePosition();
- //updateLyrics();
- }
-
- private void updateQueuePosition() {
- mPlayingQueueAdapter.setCurrent(MusicPlayerRemote.INSTANCE.getPosition());
- // if (slidingUpPanelLayout.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) {
- resetToCurrentPosition();
- //}
- }
-
- private void updateQueue() {
- mPlayingQueueAdapter
- .swapDataSet(MusicPlayerRemote.INSTANCE.getPlayingQueue(), MusicPlayerRemote.INSTANCE.getPosition());
- resetToCurrentPosition();
- }
-
- private void resetToCurrentPosition() {
- mRecyclerView.stopScroll();
- mLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.INSTANCE.getPosition() + 1, 0);
- }
-
- @Override
- public void onPause() {
- if (mRecyclerViewDragDropManager != null) {
- mRecyclerViewDragDropManager.cancelDrag();
- }
- super.onPause();
- }
-
- @Override
- public void onDestroyView() {
- if (mRecyclerViewDragDropManager != null) {
- mRecyclerViewDragDropManager.release();
- mRecyclerViewDragDropManager = null;
- }
-
- if (mRecyclerView != null) {
- mRecyclerView.setItemAnimator(null);
- mRecyclerView.setAdapter(null);
- mRecyclerView = null;
- }
-
- if (mWrappedAdapter != null) {
- WrapperAdapterUtils.releaseAll(mWrappedAdapter);
- mWrappedAdapter = null;
- }
- mPlayingQueueAdapter = null;
- mLayoutManager = null;
- super.onDestroyView();
- unbinder.unbind();
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/VolumeFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/VolumeFragment.kt
index 3fb07eea..5202281e 100755
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/VolumeFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/VolumeFragment.kt
@@ -47,19 +47,19 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
val audioManager = audioManager
if (audioManager != null) {
- volumeSeekBar!!.max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
- volumeSeekBar!!.progress = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
+ volumeSeekBar.max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
+ volumeSeekBar.progress = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
}
- volumeSeekBar!!.setOnSeekBarChangeListener(this)
+ volumeSeekBar.setOnSeekBarChangeListener(this)
}
override fun onAudioVolumeChanged(currentVolume: Int, maxVolume: Int) {
if (volumeSeekBar == null) {
return
}
- volumeSeekBar!!.max = maxVolume
- volumeSeekBar!!.progress = currentVolume
- volumeDown!!.setImageResource(if (currentVolume == 0) R.drawable.ic_volume_off_white_24dp else R.drawable.ic_volume_down_white_24dp)
+ volumeSeekBar.max = maxVolume
+ volumeSeekBar.progress = currentVolume
+ volumeDown.setImageResource(if (currentVolume == 0) R.drawable.ic_volume_off_white_24dp else R.drawable.ic_volume_down_white_24dp)
}
override fun onDestroyView() {
@@ -98,9 +98,9 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
}
private fun setProgressBarColor(newColor: Int) {
- TintHelper.setTintAuto(volumeSeekBar!!, newColor, false)
- volumeDown!!.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
- volumeUp!!.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
+ TintHelper.setTintAuto(volumeSeekBar, newColor, false)
+ volumeDown.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
+ volumeUp.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
}
private fun setTintable(color: Int) {
@@ -108,7 +108,7 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
}
fun removeThumb() {
- volumeSeekBar!!.thumb = null
+ volumeSeekBar.thumb = null
}
private fun setPauseWhenZeroVolume(pauseWhenZeroVolume: Boolean) {
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerControlsFragment.kt
index efe3631c..239e3103 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerControlsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerControlsFragment.kt
@@ -55,7 +55,7 @@ abstract class AbsPlayerControlsFragment : AbsMusicServiceFragment(), MusicProgr
}
- var prevButton: ImageButton? = null
+ /* var prevButton: ImageButton? = null
var nextButton: ImageButton? = null
var repeatButton: ImageButton? = null
var shuffleButton: ImageButton? = null
@@ -63,11 +63,12 @@ abstract class AbsPlayerControlsFragment : AbsMusicServiceFragment(), MusicProgr
var songTotalTime: TextView? = null
var songCurrentProgress: TextView? = null
var volumeContainer: View? = null
- var playPauseFab: ImageButton? = null
+ var playPauseFab: ImageButton? = null*/
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- playPauseFab = view.findViewById(R.id.player_play_pause_button)
+
+ /* playPauseFab = view.findViewById(R.id.player_play_pause_button)
prevButton = view.findViewById(R.id.player_prev_button)
nextButton = view.findViewById(R.id.player_next_button)
repeatButton = view.findViewById(R.id.player_repeat_button)
@@ -75,6 +76,6 @@ abstract class AbsPlayerControlsFragment : AbsMusicServiceFragment(), MusicProgr
progressSlider = view.findViewById(R.id.player_progress_slider)
songTotalTime = view.findViewById(R.id.player_song_total_time)
songCurrentProgress = view.findViewById(R.id.player_song_current_progress)
- volumeContainer = view.findViewById(R.id.volume_fragment_container)
+ volumeContainer = view.findViewById(R.id.volume_fragment_container)*/
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerFragment.kt
index 4eff06f4..80286a76 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/base/AbsPlayerFragment.kt
@@ -32,8 +32,6 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem
private set
private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null
- protected var toolbar: Toolbar? = null
-
override fun onAttach(context: Context?) {
super.onAttach(context)
@@ -146,6 +144,8 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem
MusicUtil.toggleFavorite(activity!!, song)
}
+ abstract fun toolbarGet(): Toolbar
+
abstract fun onShow()
abstract fun onHide()
@@ -193,7 +193,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem
else
R.drawable.ic_favorite_border_white_24dp
val drawable = RetroUtil.getTintedVectorDrawable(activity, res, toolbarIconColor())
- //toolbar!!.menu.findItem(R.id.action_toggle_favorite).setIcon(drawable).title = if (isFavorite) getString(R.string.action_remove_from_favorites) else getString(R.string.action_add_to_favorites)
+ toolbarGet().menu.findItem(R.id.action_toggle_favorite).setIcon(drawable).title = if (isFavorite) getString(R.string.action_remove_from_favorites) else getString(R.string.action_add_to_favorites)
}
}
}.execute(MusicPlayerRemote.currentSong)
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.kt
index 84054572..519cdc3f 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/GenreFragment.kt
@@ -1,12 +1,9 @@
package code.name.monkey.retromusic.ui.fragments.mainactivity
import android.os.Bundle
-import androidx.recyclerview.widget.LinearLayoutManager
import android.view.Menu
import android.view.MenuInflater
-
-import java.util.ArrayList
-
+import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.mvp.contract.GenreContract
@@ -14,6 +11,7 @@ import code.name.monkey.retromusic.mvp.presenter.GenrePresenter
import code.name.monkey.retromusic.ui.adapter.GenreAdapter
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewFragment
import code.name.monkey.retromusic.util.PreferenceUtil
+import java.util.*
class GenreFragment : AbsLibraryPagerRecyclerViewFragment(), GenreContract.GenreView {
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/LibraryFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/LibraryFragment.kt
index a9d4b4e0..9ea0ad93 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/LibraryFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/LibraryFragment.kt
@@ -7,7 +7,6 @@ import android.widget.TextView
import androidx.annotation.StringRes
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment
-import butterknife.Unbinder
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
import code.name.monkey.appthemehelper.util.ATHUtil
@@ -109,10 +108,7 @@ class LibraryFragment : AbsMainActivityFragment(), CabHolder, MainActivityFragme
appbar.addOnOffsetChangedListener(this)
mainActivity.title = null
mainActivity.setSupportActionBar(toolbar)
-
- toolbar.setNavigationOnClickListener { NavigationUtil.goToSearch(mainActivity) }
- toolbar.setOnClickListener { showMainMenu() }
- toolbar.navigationIcon = RetroUtil.getTintedDrawable(mainActivity, R.drawable.ic_search_white_24dp, ThemeStore.textColorPrimary(mainActivity))
+ toolbar.navigationIcon = RetroUtil.getTintedDrawable(mainActivity, R.drawable.ic_menu_white_24dp, ThemeStore.textColorPrimary(mainActivity))
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/folders/FoldersFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/folders/FoldersFragment.java
index 1fd8b121..5ab19f72 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/folders/FoldersFragment.java
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/folders/FoldersFragment.java
@@ -40,7 +40,6 @@ import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
-import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;
import code.name.monkey.appthemehelper.ThemeStore;
@@ -74,8 +73,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
AppBarLayout.OnOffsetChangedListener, LoaderManager.LoaderCallbacks> {
public static final String TAG = FoldersFragment.class.getSimpleName();
- public static final FileFilter AUDIO_FILE_FILTER = file -> !file.isHidden() && (file.isDirectory()
- ||
+ public static final FileFilter AUDIO_FILE_FILTER = file -> !file.isHidden() && (file.isDirectory() ||
FileUtil.fileIsMimeType(file, "audio/*", MimeTypeMap.getSingleton()) ||
FileUtil.fileIsMimeType(file, "application/opus", MimeTypeMap.getSingleton()) ||
FileUtil.fileIsMimeType(file, "application/ogg", MimeTypeMap.getSingleton()));
@@ -83,30 +81,18 @@ public class FoldersFragment extends AbsMainActivityFragment implements
private static final String PATH = "path";
private static final String CRUMBS = "crumbs";
private static final int LOADER_ID = LoaderIds.Companion.getFOLDERS_FRAGMENT();
- @BindView(R.id.coordinator_layout)
- View coordinatorLayout;
- @BindView(R.id.container)
- View container;
+ private View coordinatorLayout, container, empty;
- @BindView(R.id.title)
- TextView title;
+ private TextView title;
- @BindView(android.R.id.empty)
- View empty;
+ private Toolbar toolbar;
- @BindView(R.id.toolbar)
- Toolbar toolbar;
+ private BreadCrumbLayout breadCrumbs;
- @BindView(R.id.bread_crumbs)
- BreadCrumbLayout breadCrumbs;
-
- @BindView(R.id.app_bar)
- AppBarLayout appbar;
-
- @BindView(R.id.recycler_view)
- FastScrollRecyclerView recyclerView;
+ private AppBarLayout appBarLayout;
+ private FastScrollRecyclerView recyclerView;
private Comparator fileComparator = (lhs, rhs) -> {
if (lhs.isDirectory() && !rhs.isDirectory()) {
@@ -118,10 +104,8 @@ public class FoldersFragment extends AbsMainActivityFragment implements
(rhs.getName());
}
};
- private Unbinder unbinder;
private SongFileAdapter adapter;
private MaterialCab cab;
-
public FoldersFragment() {
}
@@ -162,6 +146,17 @@ public class FoldersFragment extends AbsMainActivityFragment implements
}
}
+ private void initViews(View view) {
+ coordinatorLayout = view.findViewById(R.id.coordinatorLayout);
+ recyclerView = view.findViewById(R.id.recyclerView);
+ appBarLayout = view.findViewById(R.id.appBarLayout);
+ breadCrumbs = view.findViewById(R.id.breadCrumbs);
+ toolbar = view.findViewById(R.id.toolbar);
+ empty = view.findViewById(android.R.id.empty);
+ title = view.findViewById(R.id.bannerTitle);
+ container = view.findViewById(R.id.container);
+ }
+
private void setCrumb(BreadCrumbLayout.Crumb crumb, boolean addToHistory) {
if (crumb == null) {
return;
@@ -215,15 +210,13 @@ public class FoldersFragment extends AbsMainActivityFragment implements
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_folder, container, false);
- unbinder = ButterKnife.bind(this, view);
+ initViews(view);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
setStatusbarColorAuto(view);
- //getMainActivity().getSlidingUpPanelLayout().setShadowHeight(0);
-
setUpAppbarColor();
setUpBreadCrumbs();
setUpRecyclerView();
@@ -238,18 +231,17 @@ public class FoldersFragment extends AbsMainActivityFragment implements
int primaryColor = ThemeStore.primaryColor(getContext());
- toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp);
+ toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
//noinspection ConstantConditions
getActivity().setTitle(null);
getMainActivity().setSupportActionBar(toolbar);
- toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
TintHelper.setTintAuto(container, primaryColor, true);
- appbar.setBackgroundColor(primaryColor);
+ appBarLayout.setBackgroundColor(primaryColor);
toolbar.setBackgroundColor(primaryColor);
breadCrumbs.setActivatedContentColor(ToolbarContentTintHelper.toolbarTitleColor(getActivity(), ColorUtil.darkenColor(primaryColor)));
breadCrumbs.setDeactivatedContentColor(ToolbarContentTintHelper.toolbarSubtitleColor(getActivity(), ColorUtil.darkenColor(primaryColor)));
- appbar.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext())));
+ appBarLayout.addOnOffsetChangedListener((appBarLayout, verticalOffset) -> getMainActivity().setLightStatusbar(!ATHUtil.isWindowBackgroundDark(getContext())));
}
private void setUpBreadCrumbs() {
@@ -261,7 +253,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
ViewUtil.setUpFastScrollRecyclerViewColor(getActivity(), recyclerView,
ThemeStore.accentColor(getActivity()));
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
- appbar.addOnOffsetChangedListener(this);
+ appBarLayout.addOnOffsetChangedListener(this);
}
private void setUpAdapter() {
@@ -286,8 +278,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
@Override
public void onDestroyView() {
- appbar.removeOnOffsetChangedListener(this);
- unbinder.unbind();
+ appBarLayout.removeOnOffsetChangedListener(this);
super.onDestroyView();
}
@@ -473,7 +464,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
- container.getPaddingRight(), appbar.getTotalScrollRange() + verticalOffset);
+ container.getPaddingRight(), this.appBarLayout.getTotalScrollRange() + verticalOffset);
}
private void checkIsEmpty() {
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/home/BannerHomeFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/home/BannerHomeFragment.kt
index 4b56b5b4..273ab2a9 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/home/BannerHomeFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/mainactivity/home/BannerHomeFragment.kt
@@ -1,18 +1,19 @@
package code.name.monkey.retromusic.ui.fragments.mainactivity.home
import android.graphics.Bitmap
+import android.graphics.Color
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
+import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import butterknife.OnClick
import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.Constants.USER_BANNER
import code.name.monkey.retromusic.Constants.USER_PROFILE
import code.name.monkey.retromusic.R
@@ -34,80 +35,37 @@ import code.name.monkey.retromusic.util.Compressor
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
-import code.name.monkey.retromusic.views.CircularImageView
-import code.name.monkey.retromusic.views.MetalRecyclerViewPager
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers
-import kotlinx.android.synthetic.main.abs_playlists.*
+import kotlinx.android.synthetic.main.fragment_banner_home.*
+import kotlinx.android.synthetic.main.home_section_content.*
import java.io.File
import java.util.*
class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallbacks, HomeContract.HomeView {
+ val disposable: CompositeDisposable = CompositeDisposable()
+ private lateinit var homePresenter: HomePresenter
+ private lateinit var contentContainerView: View
+ private lateinit var lastAdded: View
+ private lateinit var topPlayed: View
+ private lateinit var actionShuffle: View
+ private lateinit var history: View
+ private lateinit var userImage: ImageView
+ private lateinit var toolbar: Toolbar
- override fun onCreateView(inflater: LayoutInflater, viewGroup: ViewGroup?,
- savedInstanceState: Bundle?): View? {
- val view = inflater.inflate(if (PreferenceUtil.getInstance().isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home, viewGroup, false)
-
- if (!PreferenceUtil.getInstance().isHomeBanner)
- setStatusbarColorAuto(view)
-
- imageView = view.findViewById(R.id.image)
- userImage = view.findViewById(R.id.user_image)
- recentArtistRV = view.findViewById(R.id.recycler_view)
- recentAlbumRV = view.findViewById(R.id.recent_album)
- topArtistRV = view.findViewById(R.id.top_artist)
- topAlbumRV = view.findViewById(R.id.top_album)
- recentArtistContainer = view.findViewById(R.id.recent_artist_container)
- recentAlbumsContainer = view.findViewById(R.id.recent_albums_container)
- topArtistContainer = view.findViewById(R.id.top_artist_container)
- topAlbumContainer = view.findViewById(R.id.top_albums_container)
- genresRecyclerView = view.findViewById(R.id.genres)
- genreContainer = view.findViewById(R.id.genre_container)
- contentContainer = view.findViewById(R.id.content_container)
- container = view.findViewById(R.id.container)
- suggestionsSongs = view.findViewById(R.id.suggestion_songs)
- suggestionsContainer = view.findViewById(R.id.suggestion_container)
-
- /* lastAdded.setOnClickListener {
- NavigationUtil.goToPlaylistNew(activity!!, LastAddedPlaylist(activity!!))
- }
- topPlayed.setOnClickListener {
- NavigationUtil.goToPlaylistNew(activity!!, MyTopTracksPlaylist(activity!!))
- }
- actionShuffle.setOnClickListener {
- MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(activity!!).blockingFirst(), true)
- }
- history.setOnClickListener {
- NavigationUtil.goToPlaylistNew(activity!!, HistoryPlaylist(activity!!))
- }*/
- userImage.setOnClickListener {
- NavigationUtil.goToUserInfo(activity!!)
- }
- return view
+ override fun onActivityCreated(savedInstanceState: Bundle?) {
+ super.onActivityCreated(savedInstanceState)
+ mainActivity.setBottomBarVisibility(View.GONE)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, viewGroup: ViewGroup?, savedInstanceState: Bundle?): View? {
+ return inflater.inflate(if (PreferenceUtil.getInstance().isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home, viewGroup, false)
}
- private var imageView: ImageView? = null
- private lateinit var userImage: CircularImageView
- private lateinit var recentAlbumRV: MetalRecyclerViewPager
- private lateinit var topAlbumRV: MetalRecyclerViewPager
- private lateinit var topArtistRV: RecyclerView
- private lateinit var genresRecyclerView: RecyclerView
- private lateinit var suggestionsSongs: RecyclerView
- private lateinit var recentArtistRV: RecyclerView
- private lateinit var recentArtistContainer: View
- private lateinit var recentAlbumsContainer: View
- private lateinit var topArtistContainer: View
- private lateinit var topAlbumContainer: View
- private lateinit var genreContainer: View
- private lateinit var container: View
- private lateinit var contentContainer: View
- private lateinit var suggestionsContainer: View
- private lateinit var homePresenter: HomePresenter
- val disposable: CompositeDisposable = CompositeDisposable()
private val displayMetrics: DisplayMetrics
get() {
@@ -122,16 +80,12 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
val timeOfDay = c.get(Calendar.HOUR_OF_DAY)
var images = arrayOf()
- if (timeOfDay in 0..5) {
- images = resources.getStringArray(R.array.night)
- } else if (timeOfDay in 6..11) {
- images = resources.getStringArray(R.array.morning)
- } else if (timeOfDay in 12..15) {
- images = resources.getStringArray(R.array.after_noon)
- } else if (timeOfDay in 16..19) {
- images = resources.getStringArray(R.array.evening)
- } else if (timeOfDay in 20..23) {
- images = resources.getStringArray(R.array.night)
+ when (timeOfDay) {
+ in 0..5 -> images = resources.getStringArray(R.array.night)
+ in 6..11 -> images = resources.getStringArray(R.array.morning)
+ in 12..15 -> images = resources.getStringArray(R.array.after_noon)
+ in 16..19 -> images = resources.getStringArray(R.array.evening)
+ in 20..23 -> images = resources.getStringArray(R.array.night)
}
val day = images[Random().nextInt(images.size)]
@@ -141,47 +95,39 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
private fun loadTimeImage(day: String) {
- if (imageView != null) {
+ if (bannerImage != null) {
if (PreferenceUtil.getInstance().bannerImage.isEmpty()) {
Glide.with(activity).load(day)
.asBitmap()
.placeholder(R.drawable.material_design_default)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
- .into(imageView!!)
+ .into(bannerImage!!)
} else {
- loadBannerFromStorage()
+
+ disposable.add(Compressor(context!!)
+ .setQuality(100)
+ .setCompressFormat(Bitmap.CompressFormat.WEBP)
+ .compressToBitmapAsFlowable(File(PreferenceUtil.getInstance().bannerImage, USER_BANNER))
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe { bannerImage!!.setImageBitmap(it) })
}
}
}
- private fun loadBannerFromStorage() {
-
- disposable.add(Compressor(context!!)
- .setQuality(100)
- .setCompressFormat(Bitmap.CompressFormat.WEBP)
- .compressToBitmapAsFlowable(
- File(PreferenceUtil.getInstance().bannerImage, USER_BANNER))
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe { imageView!!.setImageBitmap(it) })
- }
-
private fun loadImageFromStorage(imageView: ImageView) {
-
disposable.add(Compressor(context!!)
.setMaxHeight(300)
.setMaxWidth(300)
.setQuality(75)
.setCompressFormat(Bitmap.CompressFormat.WEBP)
- .compressToBitmapAsFlowable(
- File(PreferenceUtil.getInstance().profileImage, USER_PROFILE))
+ .compressToBitmapAsFlowable(File(PreferenceUtil.getInstance().profileImage, USER_PROFILE))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
imageView.setImageBitmap(it)
}) {
- imageView.setImageDrawable(ContextCompat
- .getDrawable(context!!, R.drawable.ic_person_flat))
+ imageView.setImageDrawable(ContextCompat.getDrawable(context!!, R.drawable.ic_person_flat))
})
}
@@ -193,20 +139,55 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+ mainActivity.setBottomBarVisibility(View.GONE)
+
+ toolbar = view.findViewById(R.id.toolbar)
+
+ if (!PreferenceUtil.getInstance().isHomeBanner)
+ setStatusbarColorAuto(view)
+
+ lastAdded = view.findViewById(R.id.lastAdded)
+ lastAdded.setOnClickListener {
+ NavigationUtil.goToPlaylistNew(activity!!, LastAddedPlaylist(activity!!))
+ }
+
+ topPlayed = view.findViewById(R.id.topPlayed)
+ topPlayed.setOnClickListener {
+ NavigationUtil.goToPlaylistNew(activity!!, MyTopTracksPlaylist(activity!!))
+ }
+
+ actionShuffle = view.findViewById(R.id.actionShuffle)
+ actionShuffle.setOnClickListener {
+ MusicPlayerRemote.openAndShuffleQueue(SongLoader.getAllSongs(activity!!).blockingFirst(), true)
+ }
+
+ history = view.findViewById(R.id.history)
+ history.setOnClickListener {
+ NavigationUtil.goToPlaylistNew(activity!!, HistoryPlaylist(activity!!))
+ }
+
+ userImage = view.findViewById(R.id.userImage)
+ userImage.setOnClickListener { showMainMenu() }
+
+ homePresenter = HomePresenter(this)
+
+ contentContainerView = view.findViewById(R.id.contentContainer)
+ contentContainerView.setBackgroundColor(ThemeStore.primaryColor(context!!))
+
+ //bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!))
+
setupToolbar()
- loadImageFromStorage(userImage)
homePresenter.subscribe()
+
+ loadImageFromStorage(userImage)
getTimeOfTheDay()
}
private fun setupToolbar() {
- userImage.setOnClickListener { showMainMenu() }
- contentContainer.setBackgroundColor(ThemeStore.primaryColor(mainActivity))
- }
-
- @OnClick(R.id.searchIcon)
- internal fun search() {
- NavigationUtil.goToSearch(mainActivity)
+ toolbar.navigationIcon = TintHelper.createTintedDrawable(ContextCompat.getDrawable(context!!, R.drawable.ic_menu_white_24dp), ThemeStore.textColorPrimary(context!!))
+ mainActivity.title = null
+ mainActivity.setSupportActionBar(toolbar)
+ toolbar.setBackgroundColor(Color.TRANSPARENT)
}
override fun handleBackPress(): Boolean {
@@ -237,41 +218,46 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
override fun recentArtist(artists: ArrayList) {
recentArtistContainer.visibility = View.VISIBLE
- recentArtistRV.layoutManager = GridLayoutManager(mainActivity, 1, GridLayoutManager.HORIZONTAL, false)
- val artistAdapter = ArtistAdapter(mainActivity, artists, PreferenceUtil.getInstance().getHomeGridStyle(context!!), false, null)
- recentArtistRV.adapter = artistAdapter
+ recentArtist.apply {
+ val artistAdapter = ArtistAdapter(mainActivity, artists, PreferenceUtil.getInstance().getHomeGridStyle(context!!), false, null)
+ layoutManager = GridLayoutManager(mainActivity, 1, GridLayoutManager.HORIZONTAL, false)
+ adapter = artistAdapter
+ }
}
override fun recentAlbum(albums: ArrayList) {
recentAlbumsContainer.visibility = View.VISIBLE
- val artistAdapter = AlbumFullWithAdapter(mainActivity,
- displayMetrics)
+ val artistAdapter = AlbumFullWithAdapter(mainActivity, displayMetrics)
artistAdapter.swapData(albums)
- recentAlbumRV.adapter = artistAdapter
+ recentAlbum.adapter = artistAdapter
}
override fun topArtists(artists: ArrayList) {
topArtistContainer.visibility = View.VISIBLE
- topArtistRV.layoutManager = GridLayoutManager(mainActivity, 1, GridLayoutManager.HORIZONTAL, false)
- val artistAdapter = ArtistAdapter(mainActivity, artists, PreferenceUtil.getInstance().getHomeGridStyle(context!!), false, null)
- topArtistRV.adapter = artistAdapter
+ topArtist.apply {
+ layoutManager = GridLayoutManager(mainActivity, 1, GridLayoutManager.HORIZONTAL, false)
+ val artistAdapter = ArtistAdapter(mainActivity, artists, PreferenceUtil.getInstance().getHomeGridStyle(context!!), false, null)
+ adapter = artistAdapter
+ }
}
override fun topAlbums(albums: ArrayList) {
- topAlbumContainer.visibility = View.VISIBLE
+ topAlbumsContainer.visibility = View.VISIBLE
val artistAdapter = AlbumFullWithAdapter(mainActivity,
displayMetrics)
artistAdapter.swapData(albums)
- topAlbumRV.adapter = artistAdapter
+ topAlbum.adapter = artistAdapter
}
override fun suggestions(songs: ArrayList) {
if (!songs.isEmpty()) {
- suggestionsContainer.visibility = View.VISIBLE
+ suggestionContainer.visibility = View.VISIBLE
val artistAdapter = CollageSongAdapter(mainActivity, songs)
- suggestionsSongs.layoutManager = if (RetroUtil.isTablet()) GridLayoutManager(mainActivity, 2) else LinearLayoutManager(mainActivity)
- suggestionsSongs.adapter = artistAdapter
+ suggestionSongs.apply {
+ layoutManager = if (RetroUtil.isTablet()) GridLayoutManager(mainActivity, 2) else LinearLayoutManager(mainActivity)
+ adapter = artistAdapter
+ }
}
}
@@ -281,10 +267,11 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
override fun geners(genres: ArrayList) {
genreContainer.visibility = View.VISIBLE
- genresRecyclerView.layoutManager = LinearLayoutManager(context)
-
- val genreAdapter = GenreAdapter(activity!!, genres, R.layout.item_list)
- genresRecyclerView.adapter = genreAdapter
+ genresRecyclerView.apply {
+ val genreAdapter = GenreAdapter(activity!!, genres, R.layout.item_list)
+ layoutManager = LinearLayoutManager(context)
+ adapter = genreAdapter
+ }
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/PlayerAlbumCoverFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/PlayerAlbumCoverFragment.kt
index 6739497f..008fa552 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/PlayerAlbumCoverFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/PlayerAlbumCoverFragment.kt
@@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.viewpager.widget.ViewPager
-import butterknife.Unbinder
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.transform.ParallaxPagerTransformer
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/adaptive/AdaptiveFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/adaptive/AdaptiveFragment.kt
index eaa45107..5735ebfd 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/adaptive/AdaptiveFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/adaptive/AdaptiveFragment.kt
@@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
@@ -12,18 +13,22 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
+import kotlinx.android.synthetic.main.fragment_adaptive_player.*
class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
+ override fun toolbarGet(): Toolbar {
+ return playerToolbar
+ }
+
private var lastColor: Int = 0
- lateinit var playbackControlsFragment: AdaptivePlaybackControlsFragment
+ private lateinit var playbackControlsFragment: AdaptivePlaybackControlsFragment
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
- return inflater.inflate(R.layout.fragment_adaptive_player, container, false);
+ return inflater.inflate(R.layout.fragment_adaptive_player, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- toolbar = view.findViewById(R.id.toolbar)
setUpSubFragments()
setUpPlayerToolbar()
}
@@ -31,19 +36,21 @@ class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks
private fun setUpSubFragments() {
playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playback_controls_fragment) as AdaptivePlaybackControlsFragment
val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.player_album_cover_fragment) as PlayerAlbumCoverFragment
- playerAlbumCoverFragment.setCallbacks(this)
- playerAlbumCoverFragment.removeSlideEffect()
+ playerAlbumCoverFragment.apply {
+ removeSlideEffect()
+ }.setCallbacks(this)
}
private fun setUpPlayerToolbar() {
- val primaryColor = ATHUtil.resolveColor(context, R.attr.iconColor)
- /*toolbar!!.apply {
+ ATHUtil.resolveColor(context, R.attr.iconColor)
+ val primaryColor = ThemeStore.primaryColor(context!!)
+ playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { activity!!.onBackPressed() }
ToolbarContentTintHelper.colorizeToolbar(this, primaryColor, activity)
setTitleTextColor(primaryColor)
setSubtitleTextColor(ThemeStore.textColorSecondary(context!!))
- }.setOnMenuItemClickListener(this)*/
+ }.setOnMenuItemClickListener(this)
}
override fun onServiceConnected() {
@@ -59,10 +66,10 @@ class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks
private fun updateSong() {
val song = MusicPlayerRemote.currentSong
- /*toolbar!!.apply {
+ playerToolbar.apply {
title = song.title
subtitle = song.artistName
- }*/
+ }
}
override fun toggleFavorite(song: Song) {
@@ -80,7 +87,7 @@ class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks
playbackControlsFragment.setDark(color)
lastColor = color
callbacks!!.onPaletteColorChanged()
- //ToolbarContentTintHelper.colorizeToolbar(toolbar, ATHUtil.resolveColor(context, R.attr.iconColor), activity)
+ ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.iconColor), activity)
}
override fun onShow() {
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/adaptive/AdaptivePlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/adaptive/AdaptivePlaybackControlsFragment.kt
index 4ef44759..e607b269 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/adaptive/AdaptivePlaybackControlsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/adaptive/AdaptivePlaybackControlsFragment.kt
@@ -21,11 +21,10 @@ import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
-import code.name.monkey.retromusic.views.PlayPauseDrawable
+import kotlinx.android.synthetic.main.fragment_adaptive_player_playback_controls.*
class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
- private val playPauseDrawable: PlayPauseDrawable? = null
private var lastPlaybackControlsColor: Int = 0
private var lastDisabledPlaybackControlsColor: Int = 0
private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
@@ -45,13 +44,13 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
setUpMusicControllers()
hideVolumeIfAvailable()
- playPauseFab!!.setOnClickListener {
+ playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.pauseSong()
} else {
MusicPlayerRemote.resumePlaying()
}
- showBouceAnimation(playPauseFab!!)
+ showBouceAnimation(playPauseButton)
}
}
@@ -97,9 +96,9 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
updatePrevNextColor()
updatePlayPauseColor()
- TintHelper.setTintAuto(playPauseFab!!, MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color)), false)
- TintHelper.setTintAuto(playPauseFab!!, color, true)
- TintHelper.setTintAuto(progressSlider!!, color, false)
+ TintHelper.setTintAuto(playPauseButton, MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color)), false)
+ TintHelper.setTintAuto(playPauseButton, color, true)
+ TintHelper.setTintAuto(progressSlider, color, false)
}
private fun updatePlayPauseColor() {
@@ -107,18 +106,17 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
}
private fun setUpPlayPauseFab() {
- playPauseFab!!.setOnClickListener(PlayPauseButtonOnClickHandler())
+ playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
}
- protected fun updatePlayPauseDrawableState() {
+ private fun updatePlayPauseDrawableState() {
if (MusicPlayerRemote.isPlaying) {
- playPauseFab!!.setImageResource(R.drawable.ic_pause_white_24dp)
+ playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
} else {
- playPauseFab!!.setImageResource(R.drawable.ic_play_arrow_white_24dp)
+ playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
}
}
-
private fun setUpMusicControllers() {
setUpPlayPauseFab()
setUpPrevNext()
@@ -129,47 +127,62 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
private fun setUpPrevNext() {
updatePrevNextColor()
- nextButton!!.setOnClickListener { MusicPlayerRemote.playNextSong() }
- prevButton!!.setOnClickListener { MusicPlayerRemote.back() }
+ nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
+ previousButton.setOnClickListener { MusicPlayerRemote.back() }
}
private fun updatePrevNextColor() {
- nextButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
- prevButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
private fun setUpShuffleButton() {
- shuffleButton!!.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
+ shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
}
override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) {
- MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
- else -> shuffleButton!!.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
}
private fun setUpRepeatButton() {
- repeatButton!!.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
+ repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
}
override fun updateRepeatState() {
when (MusicPlayerRemote.repeatMode) {
MusicService.REPEAT_MODE_NONE -> {
- repeatButton!!.setImageResource(R.drawable.ic_repeat_white_24dp)
- repeatButton!!.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
+ repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
MusicService.REPEAT_MODE_ALL -> {
- repeatButton!!.setImageResource(R.drawable.ic_repeat_white_24dp)
- repeatButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
+ repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
MusicService.REPEAT_MODE_THIS -> {
- repeatButton!!.setImageResource(R.drawable.ic_repeat_one_white_24dp)
- repeatButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp)
+ repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
}
}
+ override fun onUpdateProgressViews(progress: Int, total: Int) {
+ progressSlider.max = total
+
+ val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
+ animator.duration = 1500
+ animator.interpolator = LinearInterpolator()
+ animator.start()
+
+ songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
+ songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
+ }
+
+ private fun hideVolumeIfAvailable() {
+ volumeFragmentContainer.visibility = if (PreferenceUtil.getInstance().volumeToggle) View.VISIBLE else View.GONE
+ }
public override fun show() {
//Ignore
@@ -180,7 +193,7 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
}
override fun setUpProgressSlider() {
- progressSlider!!.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
+ progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
MusicPlayerRemote.seekTo(progress)
@@ -191,19 +204,5 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
})
}
- override fun onUpdateProgressViews(progress: Int, total: Int) {
- progressSlider!!.max = total
- val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
- animator.duration = 1500
- animator.interpolator = LinearInterpolator()
- animator.start()
-
- songTotalTime!!.text = MusicUtil.getReadableDurationString(total.toLong())
- songCurrentProgress!!.text = MusicUtil.getReadableDurationString(progress.toLong())
- }
-
- private fun hideVolumeIfAvailable() {
- volumeContainer!!.visibility = if (PreferenceUtil.getInstance().volumeToggle) View.VISIBLE else View.GONE
- }
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/blur/BlurPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/blur/BlurPlaybackControlsFragment.kt
index f643ad47..90312741 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/blur/BlurPlaybackControlsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/blur/BlurPlaybackControlsFragment.kt
@@ -3,19 +3,23 @@ package code.name.monkey.retromusic.ui.fragments.player.blur
import android.animation.ObjectAnimator
import android.graphics.Color
import android.graphics.PorterDuff
+import android.graphics.drawable.ClipDrawable
+import android.graphics.drawable.LayerDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import android.view.animation.LinearInterpolator
import android.widget.SeekBar
import android.widget.TextView
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.ContextCompat
-import butterknife.BindView
-import butterknife.ButterKnife
-import butterknife.Unbinder
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.appthemehelper.util.ATHUtil
+import code.name.monkey.appthemehelper.util.ColorUtil
+import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote
@@ -27,13 +31,14 @@ import code.name.monkey.retromusic.ui.fragments.VolumeFragment
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
+import kotlinx.android.synthetic.main.fragment_player_playback_controls.*
+import kotlinx.android.synthetic.main.media_button.*
+import kotlinx.android.synthetic.main.player_time.*
+import kotlinx.android.synthetic.main.volume_controls.*
class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
- lateinit var songTitle: AppCompatTextView
- lateinit var text: TextView
-
private var lastPlaybackControlsColor: Int = 0
private var lastDisabledPlaybackControlsColor: Int = 0
private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
@@ -43,27 +48,35 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
}
- override fun onCreateView(inflater: LayoutInflater,
- container: ViewGroup?,
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
- val view = inflater.inflate(R.layout.fragment_blur_playback_controls, container, false)
- songTitle = view.findViewById(R.id.title)
- text = view.findViewById(R.id.text)
- return view
+
+ return inflater.inflate(R.layout.fragment_player_playback_controls, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setUpMusicControllers()
- volumeContainer!!.visibility = if (PreferenceUtil.getInstance().volumeToggle) View.VISIBLE else View.GONE
- val mVolumeFragment = childFragmentManager.findFragmentById(R.id.volume_fragment) as VolumeFragment
- mVolumeFragment.tintWhiteColor()
+ if (PreferenceUtil.getInstance().volumeToggle) {
+ volumeFragmentContainer.visibility = View.VISIBLE
+ } else {
+ volumeFragmentContainer.visibility = View.GONE
+ }
+
+ playPauseButton.setOnClickListener {
+ if (MusicPlayerRemote.isPlaying) {
+ MusicPlayerRemote.pauseSong()
+ } else {
+ MusicPlayerRemote.resumePlaying()
+ }
+ showBonceAnimation()
+ }
}
private fun updateSong() {
val song = MusicPlayerRemote.currentSong
- songTitle.text = song.title
+ title.text = song.title
text.text = song.artistName
}
@@ -102,41 +115,50 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
}
override fun setDark(color: Int) {
- lastPlaybackControlsColor = Color.WHITE
- lastDisabledPlaybackControlsColor = ContextCompat.getColor(context!!, R.color.md_grey_500)
+ val colorBg = ATHUtil.resolveColor(activity, android.R.attr.colorBackground)
+ if (ColorUtil.isColorLight(colorBg)) {
+ lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(activity, true)
+ lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(activity, true)
+ } else {
+ lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(activity, false)
+ lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(activity, false)
+ }
- songTitle.setTextColor(lastPlaybackControlsColor)
- text.setTextColor(lastDisabledPlaybackControlsColor)
-
- setProgressBarColor()
-
- songCurrentProgress!!.setTextColor(lastPlaybackControlsColor)
- songTotalTime!!.setTextColor(lastPlaybackControlsColor)
+ if (PreferenceUtil.getInstance().adaptiveColor) {
+ setFabColor(color)
+ } else {
+ setFabColor(ThemeStore.accentColor(context!!))
+ }
updateRepeatState()
updateShuffleState()
updatePrevNextColor()
}
- private fun setProgressBarColor() {
- TintHelper.setTintAuto(progressSlider!!, Color.WHITE, false)
+ private fun setFabColor(i: Int) {
+ TintHelper.setTintAuto(playPauseButton, MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(i)), false)
+ TintHelper.setTintAuto(playPauseButton, i, true)
+ setProgressBarColor(i)
+ }
+
+ private fun setProgressBarColor(newColor: Int) {
+ val ld = progressSlider.progressDrawable as LayerDrawable
+ val clipDrawable = ld.findDrawableByLayerId(android.R.id.progress) as ClipDrawable
+ clipDrawable.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
}
private fun setUpPlayPauseFab() {
- TintHelper.setTintAuto(playPauseFab!!, Color.WHITE, true)
- TintHelper.setTintAuto(playPauseFab!!, Color.BLACK, false)
- playPauseFab!!.setOnClickListener(PlayPauseButtonOnClickHandler())
+ playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
}
- protected fun updatePlayPauseDrawableState() {
+ private fun updatePlayPauseDrawableState() {
if (MusicPlayerRemote.isPlaying) {
- playPauseFab!!.setImageResource(R.drawable.ic_pause_white_24dp)
+ playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
} else {
- playPauseFab!!.setImageResource(R.drawable.ic_play_arrow_white_24dp)
+ playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
}
}
-
private fun setUpMusicControllers() {
setUpPlayPauseFab()
setUpPrevNext()
@@ -147,50 +169,49 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
private fun setUpPrevNext() {
updatePrevNextColor()
- nextButton!!.setOnClickListener { MusicPlayerRemote.playNextSong() }
- prevButton!!.setOnClickListener { MusicPlayerRemote.back() }
+ nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
+ previousButton.setOnClickListener { MusicPlayerRemote.back() }
}
private fun updatePrevNextColor() {
- nextButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
- prevButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
private fun setUpShuffleButton() {
- shuffleButton!!.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
+ shuffleButton.setOnClickListener { v -> MusicPlayerRemote.toggleShuffleMode() }
}
override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) {
- MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
- else -> shuffleButton!!.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
}
private fun setUpRepeatButton() {
- repeatButton!!.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
+ repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
}
override fun updateRepeatState() {
when (MusicPlayerRemote.repeatMode) {
MusicService.REPEAT_MODE_NONE -> {
- repeatButton!!.setImageResource(R.drawable.ic_repeat_white_24dp)
- repeatButton!!.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
+ repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
MusicService.REPEAT_MODE_ALL -> {
- repeatButton!!.setImageResource(R.drawable.ic_repeat_white_24dp)
- repeatButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
+ repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
MusicService.REPEAT_MODE_THIS -> {
- repeatButton!!.setImageResource(R.drawable.ic_repeat_one_white_24dp)
- repeatButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp)
+ repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
}
}
}
-
- override fun show() {
- playPauseFab!!.animate()
+ public override fun show() {
+ playPauseButton!!.animate()
.scaleX(1f)
.scaleY(1f)
.rotation(360f)
@@ -198,34 +219,61 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
.start()
}
- override fun hide() {
- if (playPauseFab != null) {
- playPauseFab!!.scaleX = 0f
- playPauseFab!!.scaleY = 0f
- playPauseFab!!.rotation = 0f
+ public override fun hide() {
+ if (playPauseButton != null) {
+ playPauseButton!!.apply {
+ scaleX = 0f
+ scaleY = 0f
+ rotation = 0f
+ }
}
}
override fun setUpProgressSlider() {
- progressSlider!!.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
+ progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) {
MusicPlayerRemote.seekTo(progress)
- onUpdateProgressViews(MusicPlayerRemote.songProgressMillis, MusicPlayerRemote.songDurationMillis)
+ onUpdateProgressViews(MusicPlayerRemote.songProgressMillis,
+ MusicPlayerRemote.songDurationMillis)
}
}
})
}
+ private fun showBonceAnimation() {
+ playPauseButton.apply {
+ clearAnimation()
+ scaleX = 0.9f
+ scaleY = 0.9f
+ visibility = View.VISIBLE
+ pivotX = (width / 2).toFloat()
+ pivotY = (height / 2).toFloat()
+
+ animate().setDuration(200)
+ .setInterpolator(DecelerateInterpolator())
+ .scaleX(1.1f)
+ .scaleY(1.1f)
+ .withEndAction {
+ animate().setDuration(200)
+ .setInterpolator(AccelerateInterpolator())
+ .scaleX(1f)
+ .scaleY(1f)
+ .alpha(1f).start()
+ }.start()
+ }
+ }
+
+
override fun onUpdateProgressViews(progress: Int, total: Int) {
- progressSlider!!.max = total
+ progressSlider.max = total
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
animator.duration = 1500
animator.interpolator = LinearInterpolator()
animator.start()
- songTotalTime!!.text = MusicUtil.getReadableDurationString(total.toLong())
- songCurrentProgress!!.text = MusicUtil.getReadableDurationString(progress.toLong())
+ songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
+ songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/blur/BlurPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/blur/BlurPlayerFragment.kt
index a29a82c3..52ce65b3 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/blur/BlurPlayerFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/blur/BlurPlayerFragment.kt
@@ -6,10 +6,7 @@ import android.preference.PreferenceManager
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import android.widget.ImageView
-import androidx.appcompat.app.AppCompatActivity
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
+import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.BlurTransformation
@@ -17,20 +14,19 @@ import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.ui.adapter.song.PlayingQueueAdapter
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
import com.bumptech.glide.Glide
-import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
+import kotlinx.android.synthetic.main.fragment_blur.*
class BlurPlayerFragment : AbsPlayerFragment() {
- lateinit var playbackControlsFragment: BlurPlaybackControlsFragment
+ override fun toolbarGet(): Toolbar {
+ return playerToolbar
+ }
+
+ private lateinit var playbackControlsFragment: BlurPlaybackControlsFragment
- private var colorBackground: ImageView? = null
private var lastColor: Int = 0
- private var playingQueueAdapter: PlayingQueueAdapter? = null
- private var layoutManager: LinearLayoutManager? = null
- private var recyclerView: RecyclerView? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
@@ -51,7 +47,7 @@ class BlurPlayerFragment : AbsPlayerFragment() {
}
private fun setUpPlayerToolbar() {
- toolbar!!.apply {
+ playerToolbar!!.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { activity!!.onBackPressed() }
ToolbarContentTintHelper.colorizeToolbar(this, Color.WHITE, activity)
@@ -66,7 +62,7 @@ class BlurPlayerFragment : AbsPlayerFragment() {
playbackControlsFragment.setDark(color)
lastColor = color
callbacks!!.onPaletteColorChanged()
- ToolbarContentTintHelper.colorizeToolbar(toolbar!!, Color.WHITE, activity)
+ ToolbarContentTintHelper.colorizeToolbar(playerToolbar!!, Color.WHITE, activity)
}
override fun toggleFavorite(song: Song) {
@@ -95,15 +91,6 @@ class BlurPlayerFragment : AbsPlayerFragment() {
override val paletteColor: Int
get() = lastColor
- override fun onDestroyView() {
- recyclerView!!.apply {
- itemAnimator = null
- adapter = null
- }
- playingQueueAdapter = null
- layoutManager = null
- super.onDestroyView()
- }
private fun updateBlur() {
val activity = activity ?: return
@@ -130,69 +117,11 @@ class BlurPlayerFragment : AbsPlayerFragment() {
override fun onServiceConnected() {
updateIsFavorite()
updateBlur()
- setUpRecyclerView()
}
override fun onPlayingMetaChanged() {
updateIsFavorite()
updateBlur()
- updateQueuePosition()
- }
-
- private fun setUpRecyclerView() {
- if (recyclerView != null) {
- val animator = RefactoredDefaultItemAnimator()
-
- playingQueueAdapter = PlayingQueueAdapter((activity as AppCompatActivity),
- MusicPlayerRemote.playingQueue,
- MusicPlayerRemote.position,
- R.layout.item_song,
- Color.WHITE)
- layoutManager = LinearLayoutManager(context)
-
- recyclerView!!.apply {
- layoutManager = layoutManager
- adapter = playingQueueAdapter
- itemAnimator = animator
- }
- layoutManager!!.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
- }
- }
-
- override fun onQueueChanged() {
- updateQueue()
- updateCurrentSong()
- }
-
- override fun onMediaStoreChanged() {
- updateQueue()
- updateCurrentSong()
- }
-
- private fun updateCurrentSong() {}
-
- private fun updateQueuePosition() {
-
- playingQueueAdapter!!.apply {
- setCurrent(MusicPlayerRemote.position)
- resetToCurrentPosition()
- }
-
- }
-
- private fun updateQueue() {
- playingQueueAdapter!!.apply {
- swapDataSet(MusicPlayerRemote.playingQueue, MusicPlayerRemote.position)
- resetToCurrentPosition()
- }
-
- }
-
- private fun resetToCurrentPosition() {
- recyclerView!!.apply {
- stopScroll()
- }
- layoutManager!!.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/cardblur/CardBlurFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/cardblur/CardBlurFragment.kt
new file mode 100644
index 00000000..b5347a69
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/cardblur/CardBlurFragment.kt
@@ -0,0 +1,151 @@
+package code.name.monkey.retromusic.ui.fragments.player.cardblur
+
+import android.graphics.Color
+import android.os.Bundle
+import android.preference.PreferenceManager
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.widget.Toolbar
+import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.glide.BlurTransformation
+import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
+import code.name.monkey.retromusic.glide.SongGlideRequest
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.model.Song
+import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
+import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
+import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment
+import com.bumptech.glide.Glide
+import kotlinx.android.synthetic.main.fragment_card_blur_player.*
+
+class CardBlurFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
+ override fun toolbarGet(): Toolbar {
+ return playerToolbar
+ }
+
+ private var lastColor: Int = 0
+ override val paletteColor: Int
+ get() = lastColor
+ private lateinit var playbackControlsFragment: CardBlurPlaybackControlsFragment
+
+
+ override fun onShow() {
+ playbackControlsFragment.show()
+ }
+
+ override fun onHide() {
+ playbackControlsFragment.hide()
+ onBackPressed()
+ }
+
+ override fun onBackPressed(): Boolean {
+ return false
+ }
+
+ override fun toolbarIconColor(): Int {
+ return Color.WHITE
+ }
+
+ override fun onColorChanged(color: Int) {
+ playbackControlsFragment.setDark(color)
+ lastColor = color
+ callbacks!!.onPaletteColorChanged()
+ ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
+
+ playerToolbar.setTitleTextColor(Color.WHITE)
+ playerToolbar.setSubtitleTextColor(Color.WHITE)
+ }
+
+ override fun toggleFavorite(song: Song) {
+ super.toggleFavorite(song)
+ if (song.id == MusicPlayerRemote.currentSong.id) {
+ updateIsFavorite()
+ }
+ }
+
+ override fun onFavoriteToggled() {
+ toggleFavorite(MusicPlayerRemote.currentSong)
+ }
+
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+
+ return inflater.inflate(R.layout.fragment_card_blur_player, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setUpSubFragments()
+ setUpPlayerToolbar()
+ }
+
+ private fun setUpSubFragments() {
+ playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as CardBlurPlaybackControlsFragment
+ val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment?
+ if (playerAlbumCoverFragment != null) {
+ playerAlbumCoverFragment.setCallbacks(this)
+ playerAlbumCoverFragment.removeEffect()
+ }
+
+ }
+
+ private fun setUpPlayerToolbar() {
+ playerToolbar.apply {
+ inflateMenu(R.menu.menu_player)
+ setNavigationOnClickListener { activity!!.onBackPressed() }
+ setTitleTextColor(Color.WHITE)
+ setSubtitleTextColor(Color.WHITE)
+ ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
+ }.setOnMenuItemClickListener(this)
+ }
+
+ override fun onServiceConnected() {
+ updateIsFavorite()
+ updateBlur()
+ updateSong()
+ }
+
+ override fun onPlayingMetaChanged() {
+ updateIsFavorite()
+ updateBlur()
+ updateSong()
+ }
+
+ private fun updateSong() {
+ val song = MusicPlayerRemote.currentSong
+ playerToolbar.apply {
+ title = song.title
+ subtitle = song.artistName
+ }
+ }
+
+ private fun updateBlur() {
+ val activity = activity ?: return
+ val blurAmount = PreferenceManager.getDefaultSharedPreferences(context)
+ .getInt("new_blur_amount", 25)
+
+ colorBackground!!.clearColorFilter()
+ SongGlideRequest.Builder.from(Glide.with(activity), MusicPlayerRemote.currentSong)
+ .checkIgnoreMediaStore(activity)
+ .generatePalette(activity)
+ .build()
+ .transform(BlurTransformation.Builder(getActivity()!!).blurRadius(blurAmount.toFloat()).build())
+ .into(object : RetroMusicColoredTarget(colorBackground!!) {
+ override fun onColorReady(color: Int) {
+ if (color == defaultFooterColor) {
+ colorBackground!!.setColorFilter(color)
+ }
+ }
+ })
+ }
+
+ companion object {
+
+ fun newInstance(): PlayerFragment {
+ return PlayerFragment()
+ }
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/cardblur/CardBlurPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/cardblur/CardBlurPlaybackControlsFragment.kt
new file mode 100644
index 00000000..f5602749
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/cardblur/CardBlurPlaybackControlsFragment.kt
@@ -0,0 +1,222 @@
+package code.name.monkey.retromusic.ui.fragments.player.cardblur
+
+import android.animation.ObjectAnimator
+import android.graphics.Color
+import android.graphics.PorterDuff
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.animation.AccelerateInterpolator
+import android.view.animation.DecelerateInterpolator
+import android.view.animation.LinearInterpolator
+import android.widget.SeekBar
+import code.name.monkey.appthemehelper.util.ColorUtil
+import code.name.monkey.appthemehelper.util.MaterialValueHelper
+import code.name.monkey.appthemehelper.util.TintHelper
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
+import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
+import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
+import code.name.monkey.retromusic.service.MusicService
+import code.name.monkey.retromusic.ui.fragments.VolumeFragment
+import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment
+import code.name.monkey.retromusic.util.MusicUtil
+import code.name.monkey.retromusic.util.PreferenceUtil
+import kotlinx.android.synthetic.main.fragment_card_blur_player_playback_controls.*
+import kotlinx.android.synthetic.main.media_button.*
+import kotlinx.android.synthetic.main.player_time.*
+import kotlinx.android.synthetic.main.volume_controls.*
+
+class CardBlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
+
+ private var lastPlaybackControlsColor: Int = 0
+ private var lastDisabledPlaybackControlsColor: Int = 0
+ private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
+
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+
+ return inflater.inflate(R.layout.fragment_card_blur_player_playback_controls, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setUpMusicControllers()
+ setupVolumeControls()
+ hideVolumeIfAvailable()
+ }
+
+ private fun hideVolumeIfAvailable() {
+ volumeFragmentContainer.visibility = if (PreferenceUtil.getInstance().volumeToggle) View.VISIBLE else View.GONE
+ }
+
+ override fun setDark(color: Int) {
+ lastPlaybackControlsColor = Color.WHITE
+ lastDisabledPlaybackControlsColor = ColorUtil.withAlpha(Color.WHITE, 0.3f)
+
+ updateRepeatState()
+ updateShuffleState()
+ updatePrevNextColor()
+ updateProgressTextColor()
+ }
+
+
+ private fun setUpPlayPauseFab() {
+ playPauseButton.apply {
+ TintHelper.setTintAuto(this, Color.WHITE, true)
+ TintHelper.setTintAuto(this, Color.BLACK, false)
+ setOnClickListener(PlayPauseButtonOnClickHandler())
+ }
+
+ }
+
+ private fun updatePlayPauseDrawableState() {
+ when {
+ MusicPlayerRemote.isPlaying -> playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ else -> playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
+ }
+ }
+
+ private fun setupVolumeControls() {
+ val volumeFragment = childFragmentManager.findFragmentById(R.id.volumeFragment) as VolumeFragment
+ volumeFragment.tintWhiteColor()
+ }
+
+ private fun updateProgressTextColor() {
+ val color = MaterialValueHelper.getPrimaryTextColor(context, false)
+ songTotalTime.setTextColor(color)
+ songCurrentProgress.setTextColor(color)
+ }
+
+
+ override fun onResume() {
+ super.onResume()
+ progressViewUpdateHelper!!.start()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ progressViewUpdateHelper!!.stop()
+ }
+
+ override fun onServiceConnected() {
+ updatePlayPauseDrawableState()
+ updateRepeatState()
+ updateShuffleState()
+ }
+
+ override fun onPlayStateChanged() {
+ updatePlayPauseDrawableState()
+ }
+
+ override fun onRepeatModeChanged() {
+ updateRepeatState()
+ }
+
+ override fun onShuffleModeChanged() {
+ updateShuffleState()
+ }
+
+ private fun setUpMusicControllers() {
+ setUpPlayPauseFab()
+ setUpPrevNext()
+ setUpRepeatButton()
+ setUpShuffleButton()
+ setUpProgressSlider()
+ }
+
+ private fun setUpPrevNext() {
+ updatePrevNextColor()
+ nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
+ previousButton.setOnClickListener { MusicPlayerRemote.back() }
+ }
+
+ private fun updatePrevNextColor() {
+ nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+
+ private fun setUpShuffleButton() {
+ shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
+ }
+
+ override fun updateShuffleState() {
+ when (MusicPlayerRemote.shuffleMode) {
+ MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ }
+
+ private fun setUpRepeatButton() {
+ repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
+ }
+
+ override fun updateRepeatState() {
+ when (MusicPlayerRemote.repeatMode) {
+ MusicService.REPEAT_MODE_NONE -> {
+ repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
+ repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ MusicService.REPEAT_MODE_ALL -> {
+ repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
+ repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ MusicService.REPEAT_MODE_THIS -> {
+ repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp)
+ repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ }
+ }
+
+ public override fun show() {
+ playPauseButton!!.animate()
+ .scaleX(1f)
+ .scaleY(1f)
+ .rotation(360f)
+ .setInterpolator(DecelerateInterpolator())
+ .start()
+ }
+
+ public override fun hide() {
+ if (playPauseButton != null) {
+ playPauseButton!!.apply {
+ scaleX = 0f
+ scaleY = 0f
+ rotation = 0f
+ }
+ }
+ }
+
+ override fun setUpProgressSlider() {
+ progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
+ override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
+ if (fromUser) {
+ MusicPlayerRemote.seekTo(progress)
+ onUpdateProgressViews(MusicPlayerRemote.songProgressMillis,
+ MusicPlayerRemote.songDurationMillis)
+ }
+ }
+ })
+ }
+
+
+ override fun onUpdateProgressViews(progress: Int, total: Int) {
+ progressSlider.max = total
+
+ val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
+ animator.duration = 1500
+ animator.interpolator = LinearInterpolator()
+ animator.start()
+
+ songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
+ songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/fit/FitFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/fit/FitFragment.kt
new file mode 100644
index 00000000..06543780
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/fit/FitFragment.kt
@@ -0,0 +1,110 @@
+package code.name.monkey.retromusic.ui.fragments.player.fit
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.widget.Toolbar
+import code.name.monkey.appthemehelper.util.ATHUtil
+import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.model.Song
+import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
+import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
+import kotlinx.android.synthetic.main.fragment_fit.*
+
+
+class FitFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
+ override fun toolbarGet(): Toolbar {
+ return playerToolbar
+ }
+
+ private var lastColor: Int = 0
+ override val paletteColor: Int
+ get() = lastColor
+
+ private lateinit var playbackControlsFragment: FitPlaybackControlsFragment
+
+ override fun onShow() {
+ playbackControlsFragment.show()
+ }
+
+ override fun onHide() {
+ playbackControlsFragment.hide()
+ onBackPressed()
+ }
+
+ override fun onBackPressed(): Boolean {
+ return false
+ }
+
+ override fun toolbarIconColor(): Int {
+ return ATHUtil.resolveColor(context, R.attr.iconColor)
+ }
+
+ override fun onColorChanged(color: Int) {
+ playbackControlsFragment.setDark(color)
+ lastColor = color
+ callbacks!!.onPaletteColorChanged()
+
+ ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.iconColor), activity)
+
+ }
+
+ override fun toggleFavorite(song: Song) {
+ super.toggleFavorite(song)
+ if (song.id == MusicPlayerRemote.currentSong.id) {
+ updateIsFavorite()
+ }
+ }
+
+ override fun onFavoriteToggled() {
+ toggleFavorite(MusicPlayerRemote.currentSong)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+
+ return inflater.inflate(R.layout.fragment_fit, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setUpSubFragments()
+ setUpPlayerToolbar()
+ }
+
+ private fun setUpSubFragments() {
+ playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as FitPlaybackControlsFragment
+
+ val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
+ playerAlbumCoverFragment.setCallbacks(this)
+ playerAlbumCoverFragment.removeEffect()
+ }
+
+ private fun setUpPlayerToolbar() {
+ playerToolbar!!.apply {
+ inflateMenu(R.menu.menu_player)
+ setNavigationOnClickListener { activity!!.onBackPressed() }
+ setOnMenuItemClickListener(this@FitFragment)
+ ToolbarContentTintHelper.colorizeToolbar(this, ATHUtil.resolveColor(context, R.attr.iconColor), activity)
+ }
+ }
+
+ override fun onServiceConnected() {
+ updateIsFavorite()
+
+ }
+
+ override fun onPlayingMetaChanged() {
+ updateIsFavorite()
+ }
+
+ companion object {
+
+ fun newInstance(): FitFragment {
+ return FitFragment()
+ }
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/fit/FitPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/fit/FitPlaybackControlsFragment.kt
new file mode 100644
index 00000000..5c508a72
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/fit/FitPlaybackControlsFragment.kt
@@ -0,0 +1,271 @@
+package code.name.monkey.retromusic.ui.fragments.player.fit
+
+import android.animation.ObjectAnimator
+import android.graphics.PorterDuff
+import android.graphics.drawable.ClipDrawable
+import android.graphics.drawable.LayerDrawable
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.animation.AccelerateInterpolator
+import android.view.animation.DecelerateInterpolator
+import android.view.animation.LinearInterpolator
+import android.widget.SeekBar
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.appthemehelper.util.ATHUtil
+import code.name.monkey.appthemehelper.util.ColorUtil
+import code.name.monkey.appthemehelper.util.MaterialValueHelper
+import code.name.monkey.appthemehelper.util.TintHelper
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
+import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
+import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
+import code.name.monkey.retromusic.service.MusicService
+import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment
+import code.name.monkey.retromusic.util.MusicUtil
+import code.name.monkey.retromusic.util.PreferenceUtil
+import kotlinx.android.synthetic.main.fragment_player_playback_controls.*
+import kotlinx.android.synthetic.main.media_button.*
+import kotlinx.android.synthetic.main.player_time.*
+import kotlinx.android.synthetic.main.volume_controls.*
+
+class FitPlaybackControlsFragment : AbsPlayerControlsFragment() {
+
+
+ private var lastPlaybackControlsColor: Int = 0
+ private var lastDisabledPlaybackControlsColor: Int = 0
+ private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+
+ return inflater.inflate(R.layout.fragment_fit_playback_controls, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setUpMusicControllers()
+ playPauseButton.setOnClickListener {
+ if (MusicPlayerRemote.isPlaying) {
+ MusicPlayerRemote.pauseSong()
+ } else {
+ MusicPlayerRemote.resumePlaying()
+ }
+ showBonceAnimation()
+ }
+ }
+
+ private fun updateSong() {
+ val song = MusicPlayerRemote.currentSong
+ title.text = song.title
+ text.text = song.artistName
+ }
+
+ override fun onResume() {
+ super.onResume()
+ progressViewUpdateHelper!!.start()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ progressViewUpdateHelper!!.stop()
+ }
+
+ override fun onServiceConnected() {
+ updatePlayPauseDrawableState()
+ updateRepeatState()
+ updateShuffleState()
+ updateSong()
+ }
+
+ override fun onPlayingMetaChanged() {
+ super.onPlayingMetaChanged()
+ updateSong()
+ }
+
+ override fun onPlayStateChanged() {
+ updatePlayPauseDrawableState()
+ }
+
+ override fun onRepeatModeChanged() {
+ updateRepeatState()
+ }
+
+ override fun onShuffleModeChanged() {
+ updateShuffleState()
+ }
+
+ override fun setDark(color: Int) {
+ val colorBg = ATHUtil.resolveColor(activity, android.R.attr.colorBackground)
+ if (ColorUtil.isColorLight(colorBg)) {
+ lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(activity, true)
+ lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(activity, true)
+ } else {
+ lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(activity, false)
+ lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(activity, false)
+ }
+
+ if (PreferenceUtil.getInstance().adaptiveColor) {
+ setFabColor(color)
+ } else {
+ setFabColor(ThemeStore.accentColor(context!!))
+ }
+
+ updateRepeatState()
+ updateShuffleState()
+ updatePrevNextColor()
+ }
+
+ private fun setFabColor(i: Int) {
+ TintHelper.setTintAuto(playPauseButton, MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(i)), false)
+ TintHelper.setTintAuto(playPauseButton, i, true)
+
+ }
+
+ private fun setUpPlayPauseFab() {
+ playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
+ }
+
+ private fun updatePlayPauseDrawableState() {
+ if (MusicPlayerRemote.isPlaying) {
+ playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ } else {
+ playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
+ }
+ }
+
+ private fun setProgressBarColor(newColor: Int) {
+ val ld = progressSlider!!.progressDrawable as LayerDrawable
+ val clipDrawable = ld.findDrawableByLayerId(android.R.id.progress) as ClipDrawable
+ clipDrawable.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
+ }
+
+
+ private fun setUpMusicControllers() {
+ setUpPlayPauseFab()
+ setUpPrevNext()
+ setUpRepeatButton()
+ setUpShuffleButton()
+ setUpProgressSlider()
+ }
+
+ private fun setUpPrevNext() {
+ updatePrevNextColor()
+ nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
+ previousButton.setOnClickListener { MusicPlayerRemote.back() }
+ }
+
+ private fun updatePrevNextColor() {
+ nextButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ previousButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+
+ private fun setUpShuffleButton() {
+ shuffleButton.setOnClickListener { v -> MusicPlayerRemote.toggleShuffleMode() }
+ }
+
+ override fun updateShuffleState() {
+ when (MusicPlayerRemote.shuffleMode) {
+ MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ }
+
+ private fun setUpRepeatButton() {
+ repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
+ }
+
+ override fun updateRepeatState() {
+ when (MusicPlayerRemote.repeatMode) {
+ MusicService.REPEAT_MODE_NONE -> {
+ repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
+ repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ MusicService.REPEAT_MODE_ALL -> {
+ repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
+ repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ MusicService.REPEAT_MODE_THIS -> {
+ repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp)
+ repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ }
+ }
+
+ public override fun show() {
+ playPauseButton!!.animate()
+ .scaleX(1f)
+ .scaleY(1f)
+ .rotation(360f)
+ .setInterpolator(DecelerateInterpolator())
+ .start()
+ }
+
+ public override fun hide() {
+ if (playPauseButton != null) {
+ playPauseButton!!.apply {
+ scaleX = 0f
+ scaleY = 0f
+ rotation = 0f
+ }
+ }
+ }
+
+ override fun setUpProgressSlider() {
+ progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
+ override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
+ if (fromUser) {
+ MusicPlayerRemote.seekTo(progress)
+ onUpdateProgressViews(MusicPlayerRemote.songProgressMillis,
+ MusicPlayerRemote.songDurationMillis)
+ }
+ }
+ })
+ }
+
+ private fun showBonceAnimation() {
+ playPauseButton.apply {
+ clearAnimation()
+ scaleX = 0.9f
+ scaleY = 0.9f
+ visibility = View.VISIBLE
+ pivotX = (width / 2).toFloat()
+ pivotY = (height / 2).toFloat()
+
+ animate().setDuration(200)
+ .setInterpolator(DecelerateInterpolator())
+ .scaleX(1.1f)
+ .scaleY(1.1f)
+ .withEndAction {
+ animate().setDuration(200)
+ .setInterpolator(AccelerateInterpolator())
+ .scaleX(1f)
+ .scaleY(1f)
+ .alpha(1f).start()
+ }.start()
+ }
+ }
+
+ override fun onUpdateProgressViews(progress: Int, total: Int) {
+ progressSlider.max = total
+
+ val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
+ animator.duration = 1500
+ animator.interpolator = LinearInterpolator()
+ animator.start()
+
+ songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
+ songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
+ }
+
+ private fun hideVolumeIfAvailable() {
+ volumeFragmentContainer.visibility = if (PreferenceUtil.getInstance().volumeToggle) View.VISIBLE else View.GONE
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/flat/FlatPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/flat/FlatPlaybackControlsFragment.kt
new file mode 100644
index 00000000..bab7b04f
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/flat/FlatPlaybackControlsFragment.kt
@@ -0,0 +1,230 @@
+package code.name.monkey.retromusic.ui.fragments.player.flat
+
+import android.animation.ObjectAnimator
+import android.graphics.PorterDuff
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.animation.DecelerateInterpolator
+import android.view.animation.LinearInterpolator
+import android.widget.SeekBar
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.appthemehelper.util.ATHUtil
+import code.name.monkey.appthemehelper.util.ColorUtil
+import code.name.monkey.appthemehelper.util.MaterialValueHelper
+import code.name.monkey.appthemehelper.util.TintHelper
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
+import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback
+import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
+import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
+import code.name.monkey.retromusic.service.MusicService
+import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerControlsFragment
+import code.name.monkey.retromusic.util.MusicUtil
+import code.name.monkey.retromusic.util.PreferenceUtil
+import kotlinx.android.synthetic.main.fragment_flat_player_playback_controls.*
+import kotlinx.android.synthetic.main.player_time.*
+import kotlinx.android.synthetic.main.volume_controls.*
+
+class FlatPlaybackControlsFragment : AbsPlayerControlsFragment(), Callback {
+
+ private var lastPlaybackControlsColor: Int = 0
+ private var lastDisabledPlaybackControlsColor: Int = 0
+ private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ return inflater.inflate(R.layout.fragment_flat_player_playback_controls, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setUpMusicControllers()
+ hideVolumeIfAvailable()
+ }
+
+ override fun onResume() {
+ super.onResume()
+ progressViewUpdateHelper!!.start()
+ }
+
+ override fun onPause() {
+ super.onPause()
+ progressViewUpdateHelper!!.stop()
+ }
+
+ override fun onUpdateProgressViews(progress: Int, total: Int) {
+ progressSlider.max = total
+
+ val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
+ animator.duration = 1500
+ animator.interpolator = LinearInterpolator()
+ animator.start()
+
+ songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
+ songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
+ }
+
+ private fun hideVolumeIfAvailable() {
+ volumeFragmentContainer.visibility = if (PreferenceUtil.getInstance().volumeToggle) View.VISIBLE else View.GONE
+ }
+
+ public override fun show() {
+ playPauseButton!!.animate()
+ .scaleX(1f)
+ .scaleY(1f)
+ .setInterpolator(DecelerateInterpolator())
+ .start()
+ }
+
+
+ public override fun hide() {
+ playPauseButton!!.apply {
+ scaleX = 0f
+ scaleY = 0f
+ rotation = 0f
+ }
+ }
+
+ override fun setDark(color: Int) {
+ val colorBg = ATHUtil.resolveColor(activity, android.R.attr.colorBackground)
+ val isDark = ColorUtil.isColorLight(colorBg)
+ if (isDark) {
+ lastPlaybackControlsColor = MaterialValueHelper.getSecondaryTextColor(activity, true)
+ lastDisabledPlaybackControlsColor = MaterialValueHelper.getSecondaryDisabledTextColor(activity, true)
+ } else {
+ lastPlaybackControlsColor = MaterialValueHelper.getPrimaryTextColor(activity, false)
+ lastDisabledPlaybackControlsColor = MaterialValueHelper.getPrimaryDisabledTextColor(activity, false)
+ }
+ val accentColor = ThemeStore.accentColor(context!!)
+ val b = PreferenceUtil.getInstance().adaptiveColor
+ updateTextColors(if (b) color else accentColor)
+ setProgressBarColor(if (b) color else accentColor)
+
+
+ updateRepeatState()
+ updateShuffleState()
+ }
+
+ private fun setProgressBarColor(dark: Int) {
+ TintHelper.setTintAuto(progressSlider!!, dark, false)
+ }
+
+ private fun updateTextColors(color: Int) {
+ val isDark = ColorUtil.isColorLight(color)
+ val darkColor = ColorUtil.darkenColor(color)
+ val colorPrimary = MaterialValueHelper.getPrimaryTextColor(context, isDark)
+ val colorSecondary = MaterialValueHelper.getSecondaryTextColor(context, ColorUtil.isColorLight(darkColor))
+
+ TintHelper.setTintAuto(playPauseButton!!, colorPrimary, false)
+ TintHelper.setTintAuto(playPauseButton!!, color, true)
+
+ title.setBackgroundColor(color)
+ title.setTextColor(colorPrimary)
+ text.setBackgroundColor(darkColor)
+ text.setTextColor(colorSecondary)
+ }
+
+ override fun onServiceConnected() {
+ updatePlayPauseDrawableState()
+ updateRepeatState()
+ updateShuffleState()
+ updateSong()
+ }
+
+ override fun onPlayingMetaChanged() {
+ super.onPlayingMetaChanged()
+ updateSong()
+ }
+
+ override fun onPlayStateChanged() {
+ updatePlayPauseDrawableState()
+ }
+
+ private fun setUpPlayPauseFab() {
+ playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
+ }
+
+ private fun updatePlayPauseDrawableState() {
+ if (MusicPlayerRemote.isPlaying) {
+ playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
+ } else {
+ playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
+ }
+ }
+
+ private fun setUpMusicControllers() {
+ setUpPlayPauseFab()
+ setUpRepeatButton()
+ setUpShuffleButton()
+ setUpProgressSlider()
+ }
+
+ private fun updateSong() {
+ //TransitionManager.beginDelayedTransition(viewGroup, new ChangeText().setChangeBehavior(ChangeText.CHANGE_BEHAVIOR_OUT_IN));
+ val song = MusicPlayerRemote.currentSong
+ title.text = song.title
+ text.text = song.artistName
+
+ }
+
+ override fun setUpProgressSlider() {
+ progressSlider!!.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
+ override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
+ if (fromUser) {
+ MusicPlayerRemote.seekTo(progress)
+ onUpdateProgressViews(MusicPlayerRemote.songProgressMillis,
+ MusicPlayerRemote.songDurationMillis)
+ }
+ }
+ })
+ }
+
+ override fun onRepeatModeChanged() {
+ updateRepeatState()
+ }
+
+ override fun onShuffleModeChanged() {
+ updateShuffleState()
+ }
+
+ private fun setUpRepeatButton() {
+ repeatButton.setOnClickListener { v -> MusicPlayerRemote.cycleRepeatMode() }
+ }
+
+ override fun updateRepeatState() {
+ when (MusicPlayerRemote.repeatMode) {
+ MusicService.REPEAT_MODE_NONE -> {
+ repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
+ repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ MusicService.REPEAT_MODE_ALL -> {
+ repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
+ repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ MusicService.REPEAT_MODE_THIS -> {
+ repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp)
+ repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ }
+ }
+
+ private fun setUpShuffleButton() {
+ shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
+ }
+
+ override fun updateShuffleState() {
+ when (MusicPlayerRemote.shuffleMode) {
+ MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
+ }
+ }
+
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/flat/FlatPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/flat/FlatPlayerFragment.kt
new file mode 100644
index 00000000..4ace7ed4
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/player/flat/FlatPlayerFragment.kt
@@ -0,0 +1,128 @@
+package code.name.monkey.retromusic.ui.fragments.player.flat
+
+import android.animation.ArgbEvaluator
+import android.animation.ValueAnimator
+import android.graphics.drawable.GradientDrawable
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.widget.Toolbar
+import code.name.monkey.appthemehelper.util.ATHUtil
+import code.name.monkey.appthemehelper.util.ColorUtil
+import code.name.monkey.appthemehelper.util.MaterialValueHelper
+import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.model.Song
+import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment
+import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
+import code.name.monkey.retromusic.util.PreferenceUtil
+import code.name.monkey.retromusic.util.ViewUtil
+import code.name.monkey.retromusic.views.DrawableGradient
+import kotlinx.android.synthetic.main.fragment_flat_player.*
+
+class FlatPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
+ override fun toolbarGet(): Toolbar {
+ return playerToolbar
+ }
+
+ private var valueAnimator: ValueAnimator? = null
+ private lateinit var flatPlaybackControlsFragment: FlatPlaybackControlsFragment
+ private var lastColor: Int = 0
+ override val paletteColor: Int
+ get() = lastColor
+
+ private fun setUpSubFragments() {
+ flatPlaybackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as FlatPlaybackControlsFragment
+ val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
+ playerAlbumCoverFragment.setCallbacks(this)
+ }
+
+ private fun setUpPlayerToolbar() {
+ playerToolbar.inflateMenu(R.menu.menu_player)
+ playerToolbar.setNavigationOnClickListener { _ -> activity!!.onBackPressed() }
+ playerToolbar.setOnMenuItemClickListener(this)
+ ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context,
+ R.attr.iconColor), activity)
+ }
+
+ private fun colorize(i: Int) {
+ if (valueAnimator != null) {
+ valueAnimator!!.cancel()
+ }
+
+ valueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), android.R.color.transparent, i)
+ valueAnimator!!.addUpdateListener { animation ->
+ val drawable = DrawableGradient(GradientDrawable.Orientation.TOP_BOTTOM,
+ intArrayOf(animation.animatedValue as Int, android.R.color.transparent), 0)
+ colorGradientBackground.background = drawable
+
+ }
+ valueAnimator!!.setDuration(ViewUtil.RETRO_MUSIC_ANIM_TIME.toLong()).start()
+ }
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ return inflater.inflate(R.layout.fragment_flat_player, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ setUpPlayerToolbar()
+ setUpSubFragments()
+
+ }
+
+ override fun onShow() {
+ flatPlaybackControlsFragment.show()
+ }
+
+ override fun onHide() {
+ flatPlaybackControlsFragment.hide()
+ onBackPressed()
+ }
+
+ override fun onBackPressed(): Boolean {
+ return false
+ }
+
+ override fun toolbarIconColor(): Int {
+ val isLight = ColorUtil.isColorLight(paletteColor)
+ return if (PreferenceUtil.getInstance().adaptiveColor)
+ MaterialValueHelper.getPrimaryTextColor(context, isLight)
+ else
+ ATHUtil.resolveColor(context, R.attr.iconColor)
+ }
+
+ override fun onColorChanged(color: Int) {
+ lastColor = color
+ flatPlaybackControlsFragment.setDark(color)
+ callbacks!!.onPaletteColorChanged()
+
+ val isLight = ColorUtil.isColorLight(color)
+
+ //TransitionManager.beginDelayedTransition(mToolbar);
+ val iconColor = if (PreferenceUtil.getInstance().adaptiveColor)
+ MaterialValueHelper.getPrimaryTextColor(context, isLight)
+ else
+ ATHUtil.resolveColor(context, R.attr.iconColor)
+ ToolbarContentTintHelper.colorizeToolbar(playerToolbar, iconColor, activity)
+ if (PreferenceUtil.getInstance().adaptiveColor) {
+ colorize(color)
+ }
+ }
+
+
+ override fun onFavoriteToggled() {
+ toggleFavorite(MusicPlayerRemote.currentSong)
+ }
+
+
+ override fun toggleFavorite(song: Song) {
+ super.toggleFavorite(song)
+ if (song.id == MusicPlayerRemote.currentSong.id) {
+ updateIsFavorite()
+ }
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/MainSettingsFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/MainSettingsFragment.java
deleted file mode 100644
index 20b352a4..00000000
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/MainSettingsFragment.java
+++ /dev/null
@@ -1,162 +0,0 @@
-package code.name.monkey.retromusic.ui.fragments.settings;
-
-import android.graphics.Bitmap;
-import android.graphics.PorterDuff;
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import java.io.File;
-import java.util.Calendar;
-import java.util.List;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.StringRes;
-import androidx.appcompat.widget.AppCompatTextView;
-import androidx.core.content.ContextCompat;
-import androidx.fragment.app.Fragment;
-import butterknife.BindView;
-import butterknife.BindViews;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import butterknife.Unbinder;
-import code.name.monkey.appthemehelper.ThemeStore;
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.ui.activities.SettingsActivity;
-import code.name.monkey.retromusic.util.Compressor;
-import code.name.monkey.retromusic.util.NavigationUtil;
-import code.name.monkey.retromusic.util.PreferenceUtil;
-import code.name.monkey.retromusic.views.CircularImageView;
-import code.name.monkey.retromusic.views.IconImageView;
-import io.reactivex.android.schedulers.AndroidSchedulers;
-import io.reactivex.disposables.CompositeDisposable;
-import io.reactivex.schedulers.Schedulers;
-
-import static code.name.monkey.retromusic.Constants.USER_PROFILE;
-
-public class MainSettingsFragment extends Fragment {
-
- @BindViews({R.id.general_settings_icon, R.id.audio_settings_icon,
- R.id.now_playing_settings_icon, R.id.personalize_settings_icon,
- R.id.image_settings_icon, R.id.notification_settings_icon, R.id.other_settings_icon})
- List icons;
-
- @BindView(R.id.container)
- ViewGroup container;
- @BindView(R.id.user_image_bottom)
- CircularImageView userImageBottom;
- @BindView(R.id.title_welcome)
- AppCompatTextView titleWelcome;
- @BindView(R.id.text)
- AppCompatTextView text;
- private Unbinder unbinder;
- private ButterKnife.Action apply = (view, index) -> {
- //noinspection ConstantConditions
- ((IconImageView) view).setColorFilter(ThemeStore.accentColor(getContext()), PorterDuff.Mode.SRC_IN);
- };
- private CompositeDisposable disposable = new CompositeDisposable();
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View layout = inflater.inflate(R.layout.fragment_main_settings, container, false);
- unbinder = ButterKnife.bind(this, layout);
- ButterKnife.apply(icons, apply);
- return layout;
- }
-
- @Override
- public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- text.setTextColor(ThemeStore.textColorSecondary(getContext()));
- titleWelcome.setTextColor(ThemeStore.textColorPrimary(getContext()));
- titleWelcome.setText(String.format("%s %s!", getTimeOfTheDay(), PreferenceUtil.getInstance().getUserName()));
- loadImageFromStorage();
- }
-
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- disposable.clear();
- unbinder.unbind();
- }
-
- @OnClick({R.id.general_settings, R.id.audio_settings, R.id.now_playing_settings,
- R.id.user_info_container, R.id.image_settings, R.id.personalize_settings, R.id.notification_settings, R.id.other_settings})
- public void onViewClicked(View view) {
- switch (view.getId()) {
- case R.id.general_settings:
- inflateFragment(new ThemeSettingsFragment(), R.string.general_settings_title);
- break;
- case R.id.audio_settings:
- inflateFragment(new AudioSettings(), R.string.pref_header_audio);
- break;
- case R.id.user_info_container:
- NavigationUtil.goToUserInfo(getActivity());
- break;
- case R.id.now_playing_settings:
- inflateFragment(new NowPlayingSettingsFragment(), R.string.now_playing);
- break;
- case R.id.personalize_settings:
- inflateFragment(new PersonaizeSettingsFragment(), R.string.personalize);
- break;
- case R.id.image_settings:
- inflateFragment(new ImageSettingFragment(), R.string.pref_header_images);
- break;
- case R.id.notification_settings:
- inflateFragment(new NotificationSettingsFragment(), R.string.notification);
- break;
- case R.id.other_settings:
- inflateFragment(new OtherSettingsFragment(), R.string.others);
- break;
- }
- }
-
- private void inflateFragment(Fragment fragment, @StringRes int title) {
- if (getActivity() != null) {
- ((SettingsActivity) getActivity()).setupFragment(fragment, title);
- }
- }
-
- private String getTimeOfTheDay() {
- String message = getString(R.string.title_good_day);
- Calendar c = Calendar.getInstance();
- int timeOfDay = c.get(Calendar.HOUR_OF_DAY);
-
- if (timeOfDay >= 0 && timeOfDay < 6) {
- message = getString(R.string.title_good_night);
- } else if (timeOfDay >= 6 && timeOfDay < 12) {
- message = getString(R.string.title_good_morning);
- } else if (timeOfDay >= 12 && timeOfDay < 16) {
- message = getString(R.string.title_good_afternoon);
- } else if (timeOfDay >= 16 && timeOfDay < 20) {
- message = getString(R.string.title_good_evening);
- } else if (timeOfDay >= 20 && timeOfDay < 24) {
- message = getString(R.string.title_good_night);
- }
- return message;
- }
-
-
- private void loadImageFromStorage() {
- //noinspection ConstantConditions
- disposable.add(new Compressor(getContext())
- .setMaxHeight(300)
- .setMaxWidth(300)
- .setQuality(75)
- .setCompressFormat(Bitmap.CompressFormat.WEBP)
- .compressToBitmapAsFlowable(
- new File(PreferenceUtil.getInstance().getProfileImage(),USER_PROFILE))
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(userImageBottom::setImageBitmap,
- throwable -> userImageBottom.setImageDrawable(ContextCompat
- .getDrawable(getContext(), R.drawable.ic_person_flat))));
- }
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/MainSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/MainSettingsFragment.kt
new file mode 100644
index 00000000..8bafb141
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/MainSettingsFragment.kt
@@ -0,0 +1,54 @@
+package code.name.monkey.retromusic.ui.fragments.settings
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.annotation.StringRes
+import androidx.fragment.app.Fragment
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.ui.activities.SettingsActivity
+import kotlinx.android.synthetic.main.fragment_main_settings.*
+
+class MainSettingsFragment : Fragment(), View.OnClickListener {
+ override fun onClick(v: View) {
+ when (v.id) {
+ R.id.generalSettings -> inflateFragment(ThemeSettingsFragment(), R.string.general_settings_title)
+ R.id.audioSettings -> inflateFragment(AudioSettings(), R.string.pref_header_audio)
+ R.id.nowPlayingSettings -> inflateFragment(NowPlayingSettingsFragment(), R.string.now_playing)
+ R.id.personalizeSettings -> inflateFragment(PersonaizeSettingsFragment(), R.string.personalize)
+ R.id.imageSettings -> inflateFragment(ImageSettingFragment(), R.string.pref_header_images)
+ R.id.notificationSettings -> inflateFragment(NotificationSettingsFragment(), R.string.notification)
+ R.id.otherSettings -> inflateFragment(OtherSettingsFragment(), R.string.others)
+ }
+ }
+
+ private val settingsIcons = arrayOf(R.id.general_settings_icon, R.id.audio_settings_icon, R.id.now_playing_settings_icon, R.id.personalize_settings_icon, R.id.image_settings_icon, R.id.notification_settings_icon, R.id.other_settings_icon)
+
+ override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
+ savedInstanceState: Bundle?): View? {
+ return inflater.inflate(R.layout.fragment_main_settings, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ settingsIcons.forEach {
+ view.findViewById(it).setColorFilter(ThemeStore.accentColor(context!!))
+ }
+ generalSettings.setOnClickListener(this)
+ audioSettings.setOnClickListener(this)
+ nowPlayingSettings.setOnClickListener(this)
+ personalizeSettings.setOnClickListener(this)
+ imageSettings.setOnClickListener(this)
+ notificationSettings.setOnClickListener(this)
+ otherSettings.setOnClickListener(this)
+ }
+
+ private fun inflateFragment(fragment: Fragment, @StringRes title: Int) {
+ if (activity != null) {
+ (activity as SettingsActivity).setupFragment(fragment, title)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NowPlayingSettingsFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NowPlayingSettingsFragment.java
index ee67454f..74da5bfe 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NowPlayingSettingsFragment.java
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/NowPlayingSettingsFragment.java
@@ -7,7 +7,7 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.preference.TwoStatePreference;
import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.RetroApplication;
+import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.util.PreferenceUtil;
/**
@@ -25,7 +25,7 @@ public class NowPlayingSettingsFragment extends AbsSettingsFragment implements
final TwoStatePreference carouselEffect = (TwoStatePreference) findPreference("carousel_effect");
carouselEffect.setOnPreferenceChangeListener((preference, newValue) -> {
- if ((Boolean) newValue && !RetroApplication.Companion.isProVersion()) {
+ if ((Boolean) newValue && !App.Companion.isProVersion()) {
showProToastAndNavigate(getActivity().getString(R.string.pref_title_toggle_carousel_effect));
return false;
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/PersonaizeSettingsFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/PersonaizeSettingsFragment.java
index 39dc558d..879c0a1a 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/PersonaizeSettingsFragment.java
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/PersonaizeSettingsFragment.java
@@ -7,7 +7,7 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.preference.TwoStatePreference;
import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.RetroApplication;
+import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.util.PreferenceUtil;
public class PersonaizeSettingsFragment extends AbsSettingsFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
@@ -16,7 +16,7 @@ public class PersonaizeSettingsFragment extends AbsSettingsFragment implements S
public void invalidateSettings() {
final TwoStatePreference cornerWindow = (TwoStatePreference) findPreference("corner_window");
cornerWindow.setOnPreferenceChangeListener((preference, newValue) -> {
- if ((Boolean) newValue && !RetroApplication.Companion.isProVersion()) {
+ if ((Boolean) newValue && !App.Companion.isProVersion()) {
showProToastAndNavigate(getActivity().getString(R.string.pref_title_round_corners));
return false;
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ThemeSettingsFragment.java b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ThemeSettingsFragment.java
index 2a4e0095..60e4f8af 100644
--- a/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ThemeSettingsFragment.java
+++ b/app/src/main/java/code/name/monkey/retromusic/ui/fragments/settings/ThemeSettingsFragment.java
@@ -14,7 +14,7 @@ import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEColorPreference
import code.name.monkey.appthemehelper.util.ColorUtil;
import code.name.monkey.appthemehelper.util.VersionUtils;
import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.RetroApplication;
+import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.ui.activities.SettingsActivity;
import code.name.monkey.retromusic.util.PreferenceUtil;
@@ -48,7 +48,7 @@ public class ThemeSettingsFragment extends AbsSettingsFragment {
generalTheme.setOnPreferenceChangeListener((preference, newValue) -> {
String theme = (String) newValue;
- if (theme.equals("color") && !RetroApplication.Companion.isProVersion()) {
+ if (theme.equals("color") && !App.Companion.isProVersion()) {
primaryColorPref.setVisible(false);
showProToastAndNavigate("Color theme");
return false;
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.java
index 34406ea7..462630f5 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.java
+++ b/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.java
@@ -22,7 +22,7 @@ import java.io.OutputStream;
import java.util.Locale;
import androidx.annotation.NonNull;
-import code.name.monkey.retromusic.RetroApplication;
+import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.model.Artist;
@@ -55,12 +55,12 @@ public class CustomArtistImageUtil {
}
public static File getFile(Artist artist) {
- File dir = new File(RetroApplication.Companion.getInstance().getFilesDir(), FOLDER_NAME);
+ File dir = new File(App.Companion.getInstance().getFilesDir(), FOLDER_NAME);
return new File(dir, getFileName(artist));
}
public void setCustomArtistImage(final Artist artist, Uri uri) {
- Glide.with(RetroApplication.Companion.getInstance())
+ Glide.with(App.Companion.getInstance())
.load(uri)
.asBitmap()
.diskCacheStrategy(DiskCacheStrategy.NONE)
@@ -70,7 +70,7 @@ public class CustomArtistImageUtil {
public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable);
e.printStackTrace();
- Toast.makeText(RetroApplication.Companion.getInstance(), e.toString(), Toast.LENGTH_LONG).show();
+ Toast.makeText(App.Companion.getInstance(), e.toString(), Toast.LENGTH_LONG).show();
}
@SuppressLint("StaticFieldLeak")
@@ -80,7 +80,7 @@ public class CustomArtistImageUtil {
@SuppressLint("ApplySharedPref")
@Override
protected Void doInBackground(Void... params) {
- File dir = new File(RetroApplication.Companion.getInstance().getFilesDir(), FOLDER_NAME);
+ File dir = new File(App.Companion.getInstance().getFilesDir(), FOLDER_NAME);
if (!dir.exists()) {
if (!dir.mkdirs()) { // create the folder
return null;
@@ -94,13 +94,13 @@ public class CustomArtistImageUtil {
succesful = ImageUtil.resizeBitmap(resource, 2048).compress(Bitmap.CompressFormat.JPEG, 100, os);
os.close();
} catch (IOException e) {
- Toast.makeText(RetroApplication.Companion.getInstance(), e.toString(), Toast.LENGTH_LONG).show();
+ Toast.makeText(App.Companion.getInstance(), e.toString(), Toast.LENGTH_LONG).show();
}
if (succesful) {
mPreferences.edit().putBoolean(getFileName(artist), true).commit();
- ArtistSignatureUtil.getInstance(RetroApplication.Companion.getInstance()).updateArtistSignature(artist.getName());
- RetroApplication.Companion.getInstance().getContentResolver().notifyChange(Uri.parse("content://media"), null); // trigger media store changed to force artist image reload
+ ArtistSignatureUtil.getInstance(App.Companion.getInstance()).updateArtistSignature(artist.getName());
+ App.Companion.getInstance().getContentResolver().notifyChange(Uri.parse("content://media"), null); // trigger media store changed to force artist image reload
}
return null;
}
@@ -116,8 +116,8 @@ public class CustomArtistImageUtil {
@Override
protected Void doInBackground(Void... params) {
mPreferences.edit().putBoolean(getFileName(artist), false).commit();
- ArtistSignatureUtil.getInstance(RetroApplication.Companion.getInstance()).updateArtistSignature(artist.getName());
- RetroApplication.Companion.getInstance().getContentResolver().notifyChange(Uri.parse("content://media"), null); // trigger media store changed to force artist image reload
+ ArtistSignatureUtil.getInstance(App.Companion.getInstance()).updateArtistSignature(artist.getName());
+ App.Companion.getInstance().getContentResolver().notifyChange(Uri.parse("content://media"), null); // trigger media store changed to force artist image reload
File file = getFile(artist);
if (!file.exists()) {
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java
index 44ad3fcb..7389773f 100755
--- a/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java
+++ b/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.java
@@ -34,7 +34,6 @@ import code.name.monkey.retromusic.ui.activities.UserInfoActivity;
import code.name.monkey.retromusic.ui.activities.WhatsNewActivity;
import static code.name.monkey.retromusic.Constants.RATE_ON_GOOGLE_PLAY;
-import static code.name.monkey.retromusic.ui.activities.GenreDetailsActivity.EXTRA_GENRE_ID;
import static code.name.monkey.retromusic.util.RetroUtil.openUrl;
@@ -60,7 +59,7 @@ public class NavigationUtil {
public static void goToPlaylistNew(@NonNull Activity activity, Playlist playlist) {
Intent intent = new Intent(activity, PlaylistDetailActivity.class);
- intent.putExtra(PlaylistDetailActivity.EXTRA_PLAYLIST, playlist);
+ intent.putExtra(PlaylistDetailActivity.Companion.getEXTRA_PLAYLIST(), playlist);
ActivityCompat.startActivity(activity, intent, null);
}
@@ -102,7 +101,7 @@ public class NavigationUtil {
public static void goToGenre(@NonNull Activity activity, @NonNull Genre genre) {
Intent intent = new Intent(activity, GenreDetailsActivity.class);
- intent.putExtra(EXTRA_GENRE_ID, genre);
+ intent.putExtra(GenreDetailsActivity.EXTRA_GENRE_ID, genre);
ActivityCompat.startActivity(activity, intent, null);
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java
index 9b93568b..4b8e93d7 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java
+++ b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.java
@@ -21,8 +21,8 @@ import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.StyleRes;
import androidx.viewpager.widget.ViewPager;
+import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.RetroApplication;
import code.name.monkey.retromusic.helper.SortOrder;
import code.name.monkey.retromusic.model.CategoryInfo;
import code.name.monkey.retromusic.transform.CascadingPageTransformer;
@@ -122,7 +122,7 @@ public final class PreferenceUtil {
public static PreferenceUtil getInstance() {
if (sInstance == null) {
- sInstance = new PreferenceUtil(RetroApplication.Companion.getContext());
+ sInstance = new PreferenceUtil(App.Companion.getContext());
}
return sInstance;
}
@@ -279,7 +279,7 @@ public final class PreferenceUtil {
public final int getLastPage() {
- return mPreferences.getInt(LAST_PAGE, R.id.action_home);
+ return mPreferences.getInt(LAST_PAGE, R.id.action_song);
}
public void setLastPage(final int value) {
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/RetroUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/RetroUtil.java
index 01bfe30b..a37f0233 100755
--- a/app/src/main/java/code/name/monkey/retromusic/util/RetroUtil.java
+++ b/app/src/main/java/code/name/monkey/retromusic/util/RetroUtil.java
@@ -46,7 +46,7 @@ import androidx.core.content.ContextCompat;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.TintHelper;
-import code.name.monkey.retromusic.RetroApplication;
+import code.name.monkey.retromusic.App;
public class RetroUtil {
@@ -84,11 +84,11 @@ public class RetroUtil {
}
public static boolean isTablet() {
- return RetroApplication.Companion.getContext().getResources().getConfiguration().smallestScreenWidthDp >= 600;
+ return App.Companion.getContext().getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
public static boolean isLandscape() {
- return RetroApplication.Companion.getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
+ return App.Companion.getContext().getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@@ -199,8 +199,8 @@ public class RetroUtil {
public static Drawable getTintedDrawable(@DrawableRes int id) {
return TintHelper
- .createTintedDrawable(ContextCompat.getDrawable(RetroApplication.Companion.getInstance(), id),
- ThemeStore.accentColor(RetroApplication.Companion.getInstance()));
+ .createTintedDrawable(ContextCompat.getDrawable(App.Companion.getInstance(), id),
+ ThemeStore.accentColor(App.Companion.getInstance()));
}
public static Bitmap createBitmap(Drawable drawable, float sizeMultiplier) {
@@ -297,9 +297,9 @@ public class RetroUtil {
public static int getStatusBarHeight() {
int result = 0;
- int resourceId = RetroApplication.Companion.getContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
+ int resourceId = App.Companion.getContext().getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
- result = RetroApplication.Companion.getContext().getResources().getDimensionPixelSize(resourceId);
+ result = App.Companion.getContext().getResources().getDimensionPixelSize(resourceId);
}
return result;
}
@@ -337,9 +337,9 @@ public class RetroUtil {
public static int getNavigationBarHeight(Activity activity) {
/* int result = 0;
- int resourceId = RetroApplication.getContext().getResources().getIdentifier("navigation_bar_height", "dimen", "android");
+ int resourceId = App.getContext().getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
- result = RetroApplication.getContext().getResources().getDimensionPixelSize(resourceId);
+ result = App.getContext().getResources().getDimensionPixelSize(resourceId);
}
return result;*/
DisplayMetrics metrics = new DisplayMetrics();
@@ -415,7 +415,7 @@ public class RetroUtil {
}
public static boolean checkNavigationBarHeight() {
- Resources resources = RetroApplication.Companion.getContext().getResources();
+ Resources resources = App.Companion.getContext().getResources();
int orientation = resources.getConfiguration().orientation;
if (!hasNavBar(resources)) {
return false;
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/SystemUtils.java b/app/src/main/java/code/name/monkey/retromusic/util/SystemUtils.java
index 2d4b7199..5e4b6072 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/SystemUtils.java
+++ b/app/src/main/java/code/name/monkey/retromusic/util/SystemUtils.java
@@ -7,7 +7,7 @@ import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.view.ViewGroup;
-import code.name.monkey.retromusic.RetroApplication;
+import code.name.monkey.retromusic.App;
public class SystemUtils {
@@ -38,9 +38,9 @@ public class SystemUtils {
public static int getNavigationBarHeight() {
int result = 0;
- int resourceId = RetroApplication.Companion.getContext().getResources().getIdentifier("navigation_bar_height", "dimen", "android");
+ int resourceId = App.Companion.getContext().getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
- result = RetroApplication.Companion.getContext().getResources().getDimensionPixelSize(resourceId);
+ result = App.Companion.getContext().getResources().getDimensionPixelSize(resourceId);
}
return result;
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/views/MaterialButtonTextColor.java b/app/src/main/java/code/name/monkey/retromusic/views/MaterialButtonTextColor.java
new file mode 100644
index 00000000..b5ff0287
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/views/MaterialButtonTextColor.java
@@ -0,0 +1,25 @@
+package code.name.monkey.retromusic.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import com.google.android.material.button.MaterialButton;
+
+import code.name.monkey.appthemehelper.ThemeStore;
+import code.name.monkey.appthemehelper.util.ColorUtil;
+import code.name.monkey.appthemehelper.util.MaterialValueHelper;
+
+public class MaterialButtonTextColor extends MaterialButton {
+ public MaterialButtonTextColor(Context context) {
+ this(context, null);
+ }
+
+ public MaterialButtonTextColor(Context context, AttributeSet attrs) {
+ this(context, attrs, -1);
+ }
+
+ public MaterialButtonTextColor(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ setTextColor(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(ThemeStore.primaryColor(getContext()))));
+ }
+}
diff --git a/app/src/main/res/drawable/navigation_item.xml b/app/src/main/res/drawable/navigation_item.xml
new file mode 100644
index 00000000..4238c61c
--- /dev/null
+++ b/app/src/main/res/drawable/navigation_item.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/navigation_view_item.xml b/app/src/main/res/drawable/navigation_view_item.xml
new file mode 100644
index 00000000..9e3c2556
--- /dev/null
+++ b/app/src/main/res/drawable/navigation_view_item.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/font/circular_std_black.otf b/app/src/main/res/font/circular_std_black.otf
deleted file mode 100755
index c62b210c..00000000
Binary files a/app/src/main/res/font/circular_std_black.otf and /dev/null differ
diff --git a/app/src/main/res/font/circular_std_book.otf b/app/src/main/res/font/circular_std_book.otf
deleted file mode 100755
index 3a1f1ad8..00000000
Binary files a/app/src/main/res/font/circular_std_book.otf and /dev/null differ
diff --git a/app/src/main/res/font/font.xml b/app/src/main/res/font/font.xml
index 485b0418..4fe9ca2d 100644
--- a/app/src/main/res/font/font.xml
+++ b/app/src/main/res/font/font.xml
@@ -1,11 +1,11 @@
\ No newline at end of file
diff --git a/app/src/main/res/font/sans_bold.ttf b/app/src/main/res/font/sans_bold.ttf
new file mode 100755
index 00000000..80497666
Binary files /dev/null and b/app/src/main/res/font/sans_bold.ttf differ
diff --git a/app/src/main/res/font/sans_regular.ttf b/app/src/main/res/font/sans_regular.ttf
new file mode 100755
index 00000000..ab605f9e
Binary files /dev/null and b/app/src/main/res/font/sans_regular.ttf differ
diff --git a/app/src/main/res/layout-land/fragment_card_blur_player.xml b/app/src/main/res/layout-land/fragment_card_blur_player.xml
index 565480bc..f8ae76af 100644
--- a/app/src/main/res/layout-land/fragment_card_blur_player.xml
+++ b/app/src/main/res/layout-land/fragment_card_blur_player.xml
@@ -8,7 +8,7 @@
android:focusable="true">
@@ -31,16 +31,20 @@
android:layout_height="match_parent"
android:orientation="vertical">
-
+
+
+
+
@@ -78,7 +82,7 @@
android:layout_marginEnd="96dp">
-
-
@@ -71,7 +66,7 @@
android:layout_height="match_parent">
@@ -42,7 +42,7 @@
android:layout_height="match_parent">
-
-
-
-
+ tools:ignore="MissingPrefix" />
-
+
@@ -61,7 +61,7 @@
android:layout_weight="0">
diff --git a/app/src/main/res/layout-xlarge-land/fragment_home.xml b/app/src/main/res/layout-xlarge-land/fragment_home.xml
index db53cbb0..6c216571 100644
--- a/app/src/main/res/layout-xlarge-land/fragment_home.xml
+++ b/app/src/main/res/layout-xlarge-land/fragment_home.xml
@@ -27,24 +27,19 @@
android:elevation="0dp"
app:elevation="0dp">
-
-
-
-
+ tools:ignore="MissingPrefix" />
-
+
diff --git a/app/src/main/res/layout-xlarge-land/fragment_player.xml b/app/src/main/res/layout-xlarge-land/fragment_player.xml
index 9284e24d..68862dbd 100644
--- a/app/src/main/res/layout-xlarge-land/fragment_player.xml
+++ b/app/src/main/res/layout-xlarge-land/fragment_player.xml
@@ -8,7 +8,7 @@
android:focusable="true">
@@ -54,13 +54,12 @@
diff --git a/app/src/main/res/layout-xlarge/fragment_home.xml b/app/src/main/res/layout-xlarge/fragment_home.xml
index 5bc9820c..76f220b8 100644
--- a/app/src/main/res/layout-xlarge/fragment_home.xml
+++ b/app/src/main/res/layout-xlarge/fragment_home.xml
@@ -28,24 +28,19 @@
android:elevation="0dp"
app:elevation="0dp">
-
-
-
-
+ tools:ignore="MissingPrefix" />
-
+
@@ -54,13 +54,12 @@
diff --git a/app/src/main/res/layout/fragment_adaptive_player.xml b/app/src/main/res/layout/fragment_adaptive_player.xml
index c377147d..1150691a 100644
--- a/app/src/main/res/layout/fragment_adaptive_player.xml
+++ b/app/src/main/res/layout/fragment_adaptive_player.xml
@@ -34,7 +34,7 @@
@@ -69,7 +69,7 @@
android:layout_weight="0">
@@ -36,13 +36,19 @@
android:orientation="vertical">
+
+
+
+
+
@@ -77,7 +82,7 @@
android:layout_gravity="bottom">
-
+
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
@@ -70,7 +67,7 @@
android:layout_height="match_parent">
-
-
-
+
+
+
+
+
+ android:clickable="true"
+ android:focusable="true"
+ android:foreground="?rectSelector"
+ android:minHeight="72dp"
+ android:orientation="horizontal"
+ tools:ignore="UnusedAttribute">
-
+ android:layout_gravity="center_vertical"
+ android:layout_weight="0"
+ app:cardCornerRadius="6dp"
+ app:cardElevation="0dp"
+ app:contentPaddingLeft="16dp">
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_marginTop="12dp"
+ android:layout_marginBottom="12dp"
+ android:layout_weight="1.0"
+ android:orientation="vertical"
+ android:paddingStart="16dp"
+ android:paddingEnd="16dp">
-
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_fit.xml b/app/src/main/res/layout/fragment_fit.xml
index b45af0d6..2fddff91 100644
--- a/app/src/main/res/layout/fragment_fit.xml
+++ b/app/src/main/res/layout/fragment_fit.xml
@@ -14,13 +14,12 @@
android:orientation="vertical">
-
-
@@ -93,98 +88,7 @@
android:textColor="?android:attr/textColorSecondary" />
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/app/src/main/res/layout/fragment_flat_player.xml b/app/src/main/res/layout/fragment_flat_player.xml
index 7f3ef825..f24de9d1 100644
--- a/app/src/main/res/layout/fragment_flat_player.xml
+++ b/app/src/main/res/layout/fragment_flat_player.xml
@@ -9,7 +9,7 @@
android:orientation="vertical">
@@ -33,26 +33,24 @@
-
-
-
-
-
-
-
+
-
-
-
-
+
diff --git a/app/src/main/res/layout/fragment_full.xml b/app/src/main/res/layout/fragment_full.xml
index 0782b84b..0bc5d5c5 100644
--- a/app/src/main/res/layout/fragment_full.xml
+++ b/app/src/main/res/layout/fragment_full.xml
@@ -44,7 +44,7 @@
diff --git a/app/src/main/res/layout/fragment_hmm_player.xml b/app/src/main/res/layout/fragment_hmm_player.xml
index b3d534a5..a65dde76 100644
--- a/app/src/main/res/layout/fragment_hmm_player.xml
+++ b/app/src/main/res/layout/fragment_hmm_player.xml
@@ -103,8 +103,7 @@
diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml
index c7649a14..4237b4c2 100755
--- a/app/src/main/res/layout/fragment_home.xml
+++ b/app/src/main/res/layout/fragment_home.xml
@@ -27,13 +27,13 @@
-
@@ -32,12 +32,11 @@
-
-
-
-
-
-
-
-
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/fragment_volume.xml b/app/src/main/res/layout/fragment_volume.xml
index ebe69c00..456c394f 100755
--- a/app/src/main/res/layout/fragment_volume.xml
+++ b/app/src/main/res/layout/fragment_volume.xml
@@ -20,7 +20,7 @@
android:id="@+id/volumeSeekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_weight="1" />
+ android:layout_weight="1" />