Adding now playing themes and KOTLIN conversion

This commit is contained in:
h4h13 2018-12-05 09:59:55 +05:30
parent d03ae1aadb
commit df37529db8
131 changed files with 5398 additions and 5304 deletions

File diff suppressed because one or more lines are too long

View file

@ -142,7 +142,6 @@ dependencies {
implementation 'com.anjlab.android.iab.v3:library:1.0.44' implementation 'com.anjlab.android.iab.v3:library:1.0.44'
/*UI Library*/ /*UI Library*/
implementation 'uk.co.chrisjenx:calligraphy:2.3.0'
implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2' implementation 'me.zhanghai.android.materialprogressbar:library:1.4.2'
implementation 'com.r0adkll:slidableactivity:2.0.6' implementation 'com.r0adkll:slidableactivity:2.0.6'
/*Backend all*/ /*Backend all*/

View file

@ -14,7 +14,7 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application <application
android:name=".RetroApplication" android:name=".App"
android:allowBackup="false" android:allowBackup="false"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"
@ -105,7 +105,7 @@
<activity android:name=".ui.activities.SettingsActivity" /> <activity android:name=".ui.activities.SettingsActivity" />
<activity <activity
android:name=".ui.activities.SearchActivity" android:name=".ui.activities.SearchActivity"
android:windowSoftInputMode="stateVisible"></activity> android:windowSoftInputMode="stateVisible"/>
<activity android:name=".ui.activities.LyricsActivity" /> <activity android:name=".ui.activities.LyricsActivity" />
<activity android:name=".ui.activities.UserInfoActivity" /> <activity android:name=".ui.activities.UserInfoActivity" />

View file

@ -1 +1 @@
<html> <head> <style type="text/css"> * { word-wrap: break-word; } {style-placeholder} a { color: #{link-color}; } a:active { color: #{link-color-active}; } ul { list-style-position: outside; padding-left: 0; padding-right: 0; margin-left: 1em; } li { padding-top: 8px; } </style> </head> <body> <h3>Version 2.2.100</h3> <ul style="line-height:150%"> <li>Click new music mix to play songs</li> <li>Gradient image option for gird list</li> <li>Clear button for playing queue</li> <li>Click toolbar (Library) to open options</li> <li>Folder list back button</li> <li>New theme Fit</li> <li>On library click on toolbar for accessing main menu </li> <li>On home click on toolbar for accessing search </li> <li>BottomSheetDialogue is now adaptable to screens, background colour and text size consistency. </li> <li>Removed coloured navigation bar option to making app adapt the primary colour</li> <li>Swipe up gesture for now playing removed, replaced with "tap to open", To achieve transparent navigation bar for desired themes. </li> <li>Improved tablet UI and home screen by adding suggestions toggle banner issues.</li> <li>Improving lyrics page</li> </ul> <p style="line-height:150%"><a href="https://github.com/h4h13/RetroMusicPlayer/wiki/FAQ">FAQ's</a> </p> <p style="line-height:150%">*If you face any UI related issues you clear app data and cache, if its not working try to uninstall and install again. </p> </body> <html> <head> <style type="text/css"> * { word-wrap: break-word; } {style-placeholder} a { color: #{link-color}; } a:active { color: #{link-color-active}; } ul { list-style-position: outside; padding-left: 0; padding-right: 0; margin-left: 1em; } li { padding-top: 8px; } </style> </head> <body> <h3>Version 2.2.100</h3> <ul style="line-height:150%"> <li>Click new music mix to play songs</li> <li>Gradient image option for gird list</li> <li>Clear button for playing queue</li> <li>Click toolbar (Library) to open options</li> <li>Folder list back button</li> <li>New theme Fit</li> <li>On library click on toolbar for accessing main menu </li> <li>On home click on toolbar for accessing search </li> <li>BottomSheetDialogue is now adaptable to screens, background colour and text size consistency. </li> <li>Removed coloured navigation bar option to making app adapt the primary colour</li> <li>Swipe up gesture for now playing removed, replaced with "tap to open", To achieve transparent navigation bar for desired themes. </li> <li>Improved tablet UI and home screen by adding suggestions toggle banner issues.</li> <li>Improving lyrics page</li> </ul> <p style="line-height:150%"><a href="https://github.com/h4h13/RetroMusicPlayer/wiki/FAQ">FAQ's</a> </p> <p style="line-height:150%">*If you face any UI related issues you clear app data and cache, if its not working try to uninstall and install again. </p> </body>

View file

@ -6,9 +6,8 @@ import code.name.monkey.appthemehelper.ThemeStore
import com.anjlab.android.iab.v3.BillingProcessor import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.TransactionDetails import com.anjlab.android.iab.v3.TransactionDetails
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import uk.co.chrisjenx.calligraphy.CalligraphyConfig
class RetroApplication : MultiDexApplication() { class App : MultiDexApplication() {
lateinit var billingProcessor: BillingProcessor lateinit var billingProcessor: BillingProcessor
@ -67,7 +66,7 @@ class RetroApplication : MultiDexApplication() {
const val PRO_VERSION_PRODUCT_ID = "pro_version" const val PRO_VERSION_PRODUCT_ID = "pro_version"
lateinit var instance: RetroApplication lateinit var instance: App
private set private set
val context: Context val context: Context

View file

@ -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<Song> list = new ArrayList<>();
list.add(song);
return create(list);
}
@NonNull
public static AddToPlaylistDialog create(ArrayList<Song> 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<Song> 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<Song> songs = getArguments().getParcelableArrayList("songs");
final ArrayList<Playlist> 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);
}
}

View file

@ -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<Song>("songs")
CreatePlaylistDialog.create(songs).show(activity!!.supportFragmentManager, "ADD_TO_PLAYLIST")
dismiss()
}
bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!))
val songs = arguments!!.getParcelableArrayList<Song>("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<Song>()
list.add(song)
return create(list)
}
fun create(songs: ArrayList<Song>): AddToPlaylistDialog {
val dialog = AddToPlaylistDialog()
val args = Bundle()
args.putParcelableArrayList("songs", songs)
dialog.arguments = args
return dialog
}
}
}

View file

@ -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();
}
}

View file

@ -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<AbsSmartPlaylist>("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
}
}
}

View file

@ -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<Song> list = new ArrayList<>();
if (song != null) {
list.add(song);
}
return create(list);
}
@NonNull
public static CreatePlaylistDialog create(ArrayList<Song> 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<Song> songs = getArguments().getParcelableArrayList("songs");
if (songs != null) {
PlaylistsUtil.addToPlaylist(getActivity(), songs, playlistId, true);
}
}
}
break;
}
dismiss();
}
}

View file

@ -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>(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<Song>("songs")
if (songs != null) {
PlaylistsUtil.addToPlaylist(activity!!, songs, playlistId, true)
}
}
}
dismiss()
}
}
companion object {
@JvmOverloads
fun create(song: Song? = null): CreatePlaylistDialog {
val list = ArrayList<Song>()
if (song != null) {
list.add(song)
}
return create(list)
}
fun create(songs: ArrayList<Song>): CreatePlaylistDialog {
val dialog = CreatePlaylistDialog()
val args = Bundle()
args.putParcelableArrayList("songs", songs)
dialog.arguments = args
return dialog
}
}
}

View file

@ -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<Playlist> list = new ArrayList<>();
list.add(playlist);
return create(list);
}
@NonNull
public static DeletePlaylistDialog create(ArrayList<Playlist> 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<Playlist> 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<Playlist> playlists = getArguments().getParcelableArrayList("playlists");
switch (view.getId()) {
case R.id.action_delete:
if (getActivity() == null)
return;
PlaylistsUtil.deletePlaylists(getActivity(), playlists);
break;
default:
}
dismiss();
}
}

View file

@ -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<Playlist>("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<Playlist>()
list.add(playlist)
return create(list)
}
fun create(playlist: ArrayList<Playlist>): DeletePlaylistDialog {
val dialog = DeletePlaylistDialog()
val args = Bundle()
args.putParcelableArrayList("playlist", playlist)
dialog.arguments = args
return dialog
}
}
}

View file

@ -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<MaterialButton, Integer> 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<MaterialButton> 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))));
}
}

View file

@ -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()
}
}
}

View file

@ -6,40 +6,17 @@ import android.text.Html
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView
import butterknife.BindView
import butterknife.ButterKnife import butterknife.ButterKnife
import butterknife.OnClick
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.model.PlaylistSong import code.name.monkey.retromusic.model.PlaylistSong
import code.name.monkey.retromusic.util.PlaylistsUtil import code.name.monkey.retromusic.util.PlaylistsUtil
import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment import code.name.monkey.retromusic.views.RoundedBottomSheetDialogFragment
import kotlinx.android.synthetic.main.dialog_remove_from_playlist.*
import java.util.* import java.util.*
class RemoveFromPlaylistDialog : RoundedBottomSheetDialogFragment() { 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<PlaylistSong>("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? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val layout = inflater.inflate(R.layout.dialog_remove_from_playlist, container, false) 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 title = R.string.remove_song_from_playlist_title
content = Html.fromHtml(getString(R.string.remove_song_x_from_playlist, songs!![0].title)) content = Html.fromHtml(getString(R.string.remove_song_x_from_playlist, songs!![0].title))
} }
this.remove!!.text = content actionRemove.text = content
this.title!!.setText(title) bannerTitle.setText(title)
this.title!!.setTextColor(ThemeStore.textColorPrimary(context!!)) bannerTitle.setTextColor(ThemeStore.textColorPrimary(context!!))
this.remove!!.setTextColor(ThemeStore.textColorSecondary(context!!)) actionRemove.setTextColor(ThemeStore.textColorSecondary(context!!))
this.cancel!!.setTextColor(ThemeStore.textColorSecondary(context!!)) actionCancel.setTextColor(ThemeStore.textColorSecondary(context!!))
actionRemove.setOnClickListener {
PlaylistsUtil.removeFromPlaylist(activity!!, songs)
}
actionCancel.setOnClickListener { dismiss() }
} }
companion object { companion object {

View file

@ -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));
}
}

View file

@ -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
}
}
}

View file

@ -15,7 +15,7 @@ import com.bumptech.glide.load.resource.drawable.GlideDrawable;
import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.target.Target;
import code.name.monkey.retromusic.R; 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.artistimage.ArtistImage;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder; import code.name.monkey.retromusic.glide.palette.BitmapPaletteTranscoder;
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper; import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper;
@ -31,7 +31,7 @@ public class ArtistGlideRequest {
private static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Artist artist, private static DrawableTypeRequest createBaseRequest(RequestManager requestManager, Artist artist,
boolean noCustomImage, boolean forceDownload) { boolean noCustomImage, boolean forceDownload) {
boolean hasCustomImage = CustomArtistImageUtil.getInstance(RetroApplication.Companion.getInstance()) boolean hasCustomImage = CustomArtistImageUtil.getInstance(App.Companion.getInstance())
.hasCustomArtistImage(artist); .hasCustomArtistImage(artist);
if (noCustomImage || !hasCustomImage) { if (noCustomImage || !hasCustomImage) {
return requestManager.load(new ArtistImage(artist.getName(), forceDownload)); return requestManager.load(new ArtistImage(artist.getName(), forceDownload));
@ -41,7 +41,7 @@ public class ArtistGlideRequest {
} }
private static Key createSignature(Artist artist) { private static Key createSignature(Artist artist) {
return ArtistSignatureUtil.getInstance(RetroApplication.Companion.getInstance()) return ArtistSignatureUtil.getInstance(App.Companion.getInstance())
.getArtistSignature(artist.getName()); .getArtistSignature(artist.getName());
} }

View file

@ -7,7 +7,6 @@ import com.bumptech.glide.request.animation.GlideAnimation
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R 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.BitmapPaletteTarget
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil

View file

@ -12,7 +12,7 @@ import android.provider.MediaStore
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
import code.name.monkey.retromusic.R 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.loaders.SongLoader
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService import code.name.monkey.retromusic.service.MusicService
@ -33,7 +33,7 @@ object MusicPlayerRemote {
private val castSession: CastSession? private val castSession: CastSession?
get() { get() {
val castSession = CastContext.getSharedInstance(RetroApplication.instance).sessionManager.currentCastSession val castSession = CastContext.getSharedInstance(App.instance).sessionManager.currentCastSession
if (castSession != null) { if (castSession != null) {
playbackLocation = PlaybackLocation.REMOTE playbackLocation = PlaybackLocation.REMOTE
} else { } else {
@ -48,7 +48,7 @@ object MusicPlayerRemote {
val currentSong: Song val currentSong: Song
get() = if (musicService != null) { get() = if (musicService != null) {
musicService!!.currentSong musicService!!.currentSong
} else Song.EMPTY_SONG } else Song.emptySong
/** /**
* Async * Async

View file

@ -1,26 +1,22 @@
package code.name.monkey.retromusic.helper.menu package code.name.monkey.retromusic.helper.menu
import android.app.Activity import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
import android.view.MenuItem import android.view.MenuItem
import androidx.appcompat.app.AppCompatActivity
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 code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.helper.MusicPlayerRemote 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). * @author Hemanth S (h4h13).
*/ */
object GenreMenuHelper { object GenreMenuHelper {
fun handleMenuClick(activity: AppCompatActivity, fun handleMenuClick(activity: AppCompatActivity, genre: Genre, item: MenuItem): Boolean {
genre: Genre,
item: MenuItem): Boolean {
when (item.itemId) { when (item.itemId) {
R.id.action_play -> { R.id.action_play -> {
MusicPlayerRemote.openQueue(getGenreSongs(activity, genre), 0, true) MusicPlayerRemote.openQueue(getGenreSongs(activity, genre), 0, true)

View file

@ -9,7 +9,7 @@ import android.widget.Toast
import java.util.ArrayList import java.util.ArrayList
import code.name.monkey.retromusic.R 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.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog import code.name.monkey.retromusic.dialogs.DeletePlaylistDialog
import code.name.monkey.retromusic.dialogs.RenamePlaylistDialog import code.name.monkey.retromusic.dialogs.RenamePlaylistDialog
@ -76,8 +76,8 @@ object PlaylistMenuHelper {
private class SavePlaylistAsyncTask internal constructor(context: Context) : WeakContextAsyncTask<Playlist, String, String>(context) { private class SavePlaylistAsyncTask internal constructor(context: Context) : WeakContextAsyncTask<Playlist, String, String>(context) {
override fun doInBackground(vararg params: Playlist): String { override fun doInBackground(vararg params: Playlist): String {
return String.format(RetroApplication.instance.applicationContext.getString(R.string return String.format(App.instance.applicationContext.getString(R.string
.saved_playlist_to), PlaylistsUtil.savePlaylist(RetroApplication.instance.applicationContext, params[0]).blockingFirst()) .saved_playlist_to), PlaylistsUtil.savePlaylist(App.instance.applicationContext, params[0]).blockingFirst())
} }
override fun onPostExecute(string: String) { override fun onPostExecute(string: String) {

View file

@ -119,7 +119,7 @@ object SongLoader {
val song: Song = if (cursor != null && cursor.moveToFirst()) { val song: Song = if (cursor != null && cursor.moveToFirst()) {
getSongFromCursorImpl(cursor) getSongFromCursorImpl(cursor)
} else { } else {
Song.EMPTY_SONG Song.emptySong
} }
cursor?.close() cursor?.close()
e.onNext(song) e.onNext(song)

View file

@ -36,6 +36,6 @@ class Album {
} }
fun safeGetFirstSong(): Song { fun safeGetFirstSong(): Song {
return if (songs!!.isEmpty()) Song.EMPTY_SONG else songs[0] return if (songs!!.isEmpty()) Song.emptySong else songs[0]
} }
} }

View file

@ -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<Genre> CREATOR = new Creator<Genre>() {
@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 + '\'' +
'}';
}
}

View file

@ -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
}
}

View file

@ -64,7 +64,9 @@ open class Song : Parcelable {
} }
companion object { companion object {
val EMPTY_SONG = Song(-1, "", -1, -1, -1, "", -1, -1, "", -1, "")
var emptySong = Song(-1, "", -1, -1, -1, "", -1, -1, "", -1, "")
@JvmField @JvmField
val CREATOR: Parcelable.Creator<Song> = object : Parcelable.Creator<Song> { val CREATOR: Parcelable.Creator<Song> = object : Parcelable.Creator<Song> {
override fun createFromParcel(source: Parcel): Song { override fun createFromParcel(source: Parcel): Song {

View file

@ -1,13 +1,12 @@
package code.name.monkey.retromusic.mvp.presenter; package code.name.monkey.retromusic.mvp.presenter;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.NonNull;
import code.name.monkey.retromusic.model.Artist; import code.name.monkey.retromusic.model.Artist;
import code.name.monkey.retromusic.mvp.Presenter; import code.name.monkey.retromusic.mvp.Presenter;
import code.name.monkey.retromusic.mvp.contract.ArtistDetailContract; import code.name.monkey.retromusic.mvp.contract.ArtistDetailContract;
import code.name.monkey.retromusic.ui.activities.ArtistDetailActivity;
import static code.name.monkey.retromusic.ui.activities.ArtistDetailActivity.EXTRA_ARTIST_ID;
/** /**
@ -38,7 +37,7 @@ public class ArtistDetailsPresenter extends Presenter implements ArtistDetailCon
@Override @Override
public void loadArtistById() { 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()) .subscribeOn(schedulerProvider.computation())
.observeOn(schedulerProvider.ui()) .observeOn(schedulerProvider.ui())
.doOnSubscribe(disposable1 -> view.loading()) .doOnSubscribe(disposable1 -> view.loading())

View file

@ -21,7 +21,7 @@ import androidx.fragment.app.DialogFragment;
import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
import code.name.monkey.retromusic.R; 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.ui.fragments.NowPlayingScreen;
import code.name.monkey.retromusic.util.NavigationUtil; import code.name.monkey.retromusic.util.NavigationUtil;
import code.name.monkey.retromusic.util.PreferenceUtil; import code.name.monkey.retromusic.util.PreferenceUtil;
@ -97,8 +97,8 @@ public class NowPlayingScreenPreferenceDialog extends DialogFragment implements
nowPlayingScreen.equals(NowPlayingScreen.TINY) || nowPlayingScreen.equals(NowPlayingScreen.TINY) ||
nowPlayingScreen.equals(NowPlayingScreen.BLUR_CARD)|| nowPlayingScreen.equals(NowPlayingScreen.BLUR_CARD)||
nowPlayingScreen.equals(NowPlayingScreen.ADAPTIVE)) nowPlayingScreen.equals(NowPlayingScreen.ADAPTIVE))
&& !RetroApplication.Companion.isProVersion();*/ && !App.Companion.isProVersion();*/
return !RetroApplication.Companion.isProVersion(); return !App.Companion.isProVersion();
} }
@Override @Override

View file

@ -6,7 +6,7 @@ import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import code.name.monkey.retromusic.Injection; 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.AlbumLoader;
import code.name.monkey.retromusic.loaders.ArtistLoader; import code.name.monkey.retromusic.loaders.ArtistLoader;
import code.name.monkey.retromusic.loaders.GenreLoader; import code.name.monkey.retromusic.loaders.GenreLoader;
@ -41,7 +41,7 @@ public class RepositoryImpl implements Repository {
public static synchronized RepositoryImpl getInstance() { public static synchronized RepositoryImpl getInstance() {
if (INSTANCE == null) { if (INSTANCE == null) {
INSTANCE = new RepositoryImpl(RetroApplication.Companion.getInstance()); INSTANCE = new RepositoryImpl(App.Companion.getInstance());
} }
return INSTANCE; return INSTANCE;
} }

View file

@ -6,7 +6,7 @@ import java.io.File;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; 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 code.name.monkey.retromusic.rest.service.KuGouApiService;
import okhttp3.Cache; import okhttp3.Cache;
import okhttp3.Call; import okhttp3.Call;
@ -69,7 +69,7 @@ public class KogouClient {
return new OkHttpClient.Builder() return new OkHttpClient.Builder()
.addInterceptor(interceptor) .addInterceptor(interceptor)
.cache(createDefaultCache(RetroApplication.Companion.getInstance())) .cache(createDefaultCache(App.Companion.getInstance()))
.addInterceptor(createCacheControlInterceptor()); .addInterceptor(createCacheControlInterceptor());
} }

View file

@ -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 <code>MultiPlayer</code>
*/
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 <code>player</code> 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 <code>player</code> 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();
}
}
}

View file

@ -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
}
}

File diff suppressed because it is too large Load diff

View file

@ -13,7 +13,6 @@ import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import butterknife.ButterKnife import butterknife.ButterKnife
import butterknife.OnClick
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ColorUtil import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.TintHelper import code.name.monkey.appthemehelper.util.TintHelper
@ -49,9 +48,9 @@ import java.util.*
class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContract.AlbumDetailsView { 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 var album: Album? = null
private set private set
@ -82,13 +81,12 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
val albumId = intent.getIntExtra(EXTRA_ALBUM_ID, -1) val albumId = intent.getIntExtra(EXTRA_ALBUM_ID, -1)
albumDetailsPresenter = AlbumDetailsPresenter(this, albumId) albumDetailsPresenter = AlbumDetailsPresenter(this, albumId)
albumDetailsPresenter!!.subscribe() albumDetailsPresenter.subscribe()
setupRecyclerView() setupRecyclerView()
setupToolbarMarginHeight() setupToolbarMarginHeight()
contentContainer.setOnScrollChangeListener { _: NestedScrollView?, _: Int, scrollY: Int, _: Int, oldScrollY: Int ->
contentContainer.setOnScrollChangeListener { v: NestedScrollView?, scrollX: Int, scrollY: Int, oldScrollX: Int, oldScrollY: Int ->
run { run {
if (scrollY > oldScrollY) { if (scrollY > oldScrollY) {
actionShuffleAll!!.setShowTitle(false) actionShuffleAll!!.setShowTitle(false)
@ -98,31 +96,40 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
} }
} }
} }
actionShuffleAll.setOnClickListener { MusicPlayerRemote.openAndShuffleQueue(album!!.songs!!, true) }
artistImage.setOnClickListener {
val artistPairs = arrayOf<Pair<*, *>>(Pair.create(image, resources.getString(R.string.transition_artist_image)))
NavigationUtil.goToArtist(this, album!!.artistId, *artistPairs)
}
} }
private fun setupRecyclerView() { private fun setupRecyclerView() {
adapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song) simpleSongAdapter = SimpleSongAdapter(this, ArrayList(), R.layout.item_song)
recyclerView.apply { recyclerView.apply {
layoutManager = LinearLayoutManager(this@AlbumDetailsActivity) layoutManager = LinearLayoutManager(this@AlbumDetailsActivity)
itemAnimator = DefaultItemAnimator() itemAnimator = DefaultItemAnimator()
isNestedScrollingEnabled = false isNestedScrollingEnabled = false
adapter = adapter adapter = simpleSongAdapter
} }
} }
private fun setupToolbarMarginHeight() { 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) setSupportActionBar(toolbar)
supportActionBar!!.title = null 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) { if (toolbar != null && !PreferenceUtil.getInstance().fullScreenMode) {
val params = toolbar!!.layoutParams as ViewGroup.MarginLayoutParams val params = toolbar!!.layoutParams as ViewGroup.MarginLayoutParams
@ -131,45 +138,29 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
} }
if (appBarLayout != null) { if (appBarLayout != null) {
appBarLayout!!.addOnOffsetChangedListener(object : AppBarStateChangeListener() { appBarLayout!!.apply {
override fun onStateChanged(appBarLayout: AppBarLayout, state: AppBarStateChangeListener.State) { addOnOffsetChangedListener(object : AppBarStateChangeListener() {
val color: Int override fun onStateChanged(appBarLayout: AppBarLayout, state: AppBarStateChangeListener.State) {
when (state) { val color: Int = when (state) {
AppBarStateChangeListener.State.COLLAPSED -> { AppBarStateChangeListener.State.COLLAPSED -> {
setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(this@AlbumDetailsActivity))) setLightStatusbar(ColorUtil.isColorLight(ThemeStore.primaryColor(this@AlbumDetailsActivity)))
color = ThemeStore.primaryColor(this@AlbumDetailsActivity) ThemeStore.primaryColor(this@AlbumDetailsActivity)
} }
AppBarStateChangeListener.State.EXPANDED, AppBarStateChangeListener.State.IDLE -> { AppBarStateChangeListener.State.EXPANDED, AppBarStateChangeListener.State.IDLE -> {
setLightStatusbar(false) setLightStatusbar(false)
color = Color.TRANSPARENT Color.TRANSPARENT
} }
else -> {
setLightStatusbar(false)
color = 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<*, *>>(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() { override fun onPause() {
super.onPause() super.onPause()
albumDetailsPresenter!!.unsubscribe() albumDetailsPresenter.unsubscribe()
} }
override fun loading() { override fun loading() {
@ -196,7 +187,8 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
loadAlbumCover() loadAlbumCover()
loadMoreFrom(album) loadMoreFrom(album)
adapter!!.swapDataSet(album.songs)
simpleSongAdapter.swapDataSet(album.songs)
} }
private fun loadMoreFrom(album: Album) { private fun loadMoreFrom(album: Album) {
@ -213,20 +205,19 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
}) })
} }
val albums = ArtistLoader.getArtist(this, album.artistId) val albums = ArtistLoader.getArtist(this, album.artistId).blockingFirst().albums
.blockingFirst().albums
albums!!.remove(album) albums!!.remove(album)
if (!albums.isEmpty()) { if (!albums.isEmpty()) {
moreTitle.visibility = View.VISIBLE moreTitle.visibility = View.VISIBLE
moreRecyclerView!!.visibility = View.VISIBLE moreRecyclerView.visibility = View.VISIBLE
} else { } else {
return return
} }
moreTitle.text = String.format("More from %s", album.artistName) moreTitle.text = String.format("More from %s", album.artistName)
val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null) val albumAdapter = HorizontalAlbumAdapter(this, albums, false, null)
moreRecyclerView!!.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false) moreRecyclerView.layoutManager = GridLayoutManager(this, 1, GridLayoutManager.HORIZONTAL, false)
moreRecyclerView!!.adapter = albumAdapter moreRecyclerView.adapter = albumAdapter
} }
private fun loadAlbumCover() { private fun loadAlbumCover() {
@ -262,7 +253,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
private fun handleSortOrderMenuItem(item: MenuItem): Boolean { private fun handleSortOrderMenuItem(item: MenuItem): Boolean {
var sortOrder: String? = null var sortOrder: String? = null
val songs = adapter!!.dataSet val songs = simpleSongAdapter.dataSet
when (item.itemId) { when (item.itemId) {
R.id.action_play_next -> { R.id.action_play_next -> {
MusicPlayerRemote.playNext(songs) MusicPlayerRemote.playNext(songs)
@ -327,7 +318,7 @@ class AlbumDetailsActivity : AbsSlidingMusicPanelActivity(), AlbumDetailsContrac
} }
private fun reload() { private fun reload() {
albumDetailsPresenter!!.subscribe() albumDetailsPresenter.subscribe()
} }
companion object { companion object {

View file

@ -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<LastFmArtist>() {
@Override
public void onResponse(@NonNull Call<LastFmArtist> call,
@NonNull Response<LastFmArtist> 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<LastFmArtist> 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<Song> 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();
}
}

View file

@ -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<LastFmArtist> {
override fun onResponse(call: Call<LastFmArtist>,
response: Response<LastFmArtist>) {
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<LastFmArtist>, 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<View>(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
}
}

View file

@ -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(); } } 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(); } }

View file

@ -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<Song> 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();
}
}

View file

@ -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<Song>) {
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"
}
}

View file

@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.* import android.content.*
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.Bundle import android.os.Bundle
import android.os.Handler
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.provider.MediaStore import android.provider.MediaStore
import android.util.Log import android.util.Log
@ -12,8 +13,11 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import butterknife.ButterKnife 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.R
import code.name.monkey.retromusic.RetroApplication
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SearchQueryHelper import code.name.monkey.retromusic.helper.SearchQueryHelper
import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks 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.service.MusicService
import code.name.monkey.retromusic.ui.activities.base.AbsSlidingMusicPanelActivity 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.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.ui.fragments.mainactivity.home.BannerHomeFragment
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.google.android.material.bottomnavigation.BottomNavigationView
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.activity_main_drawer_layout.*
import java.util.* 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 var blockRequestPermissions: Boolean = false
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
@ -63,16 +69,23 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
ButterKnife.bind(this) ButterKnife.bind(this)
getBottomNavigationView()!!.setOnNavigationItemSelectedListener(this) getBottomNavigationView()!!.setOnNavigationItemSelectedListener {
PreferenceUtil.getInstance().lastPage = it.itemId
selectedFragment(it.itemId)
true
}
setUpDrawerLayout()
if (savedInstanceState == null) { if (savedInstanceState == null) {
selectedFragment(PreferenceUtil.getInstance().lastPage) setMusicChooser(PreferenceUtil.getInstance().lastMusicChooser)
} else { } else {
restoreCurrentFragment() restoreCurrentFragment();
} }
checkShowChangelog() checkShowChangelog()
if (!RetroApplication.isProVersion && !PreferenceManager.getDefaultSharedPreferences(this).getBoolean("shown", false)) { if (!App.isProVersion && !PreferenceManager.getDefaultSharedPreferences(this).getBoolean("shown", false)) {
showPromotionalOffer() showPromotionalOffer()
} }
} }
@ -104,7 +117,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
intent.putExtra("expand", false) intent.putExtra("expand", false)
} }
} }
} }
override fun onDestroy() { override fun onDestroy() {
@ -114,16 +126,12 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this) PreferenceUtil.getInstance().unregisterOnSharedPreferenceChangedListener(this)
} }
fun setCurrentFragment(fragment: Fragment, isStackAdd: Boolean, tag: String) { private fun setCurrentFragment(fragment: Fragment) {
val fragmentTransaction = supportFragmentManager.beginTransaction() supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment, null).commit()
fragmentTransaction.replace(R.id.fragment_container, fragment, tag)
if (isStackAdd) {
fragmentTransaction.addToBackStack(tag)
}
fragmentTransaction.commit()
currentFragment = fragment as MainActivityFragmentCallbacks currentFragment = fragment as MainActivityFragmentCallbacks
} }
private fun restoreCurrentFragment() { private fun restoreCurrentFragment() {
currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as MainActivityFragmentCallbacks 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) { if (intent.action != null && intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) {
val songs = SearchQueryHelper.getSongs(this, intent.extras!!) val songs = SearchQueryHelper.getSongs(this, intent.extras!!)
if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) { if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
MusicPlayerRemote.openAndShuffleQueue(songs, true) MusicPlayerRemote.openAndShuffleQueue(songs, true)
} else { } else {
@ -148,15 +155,14 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
handled = true handled = true
} }
if (uri != null && uri.toString().length > 0) { if (uri != null && uri.toString().isNotEmpty()) {
MusicPlayerRemote.playFromUri(uri) MusicPlayerRemote.playFromUri(uri)
handled = true handled = true
} else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) { } else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) {
val id = parseIdFromIntent(intent, "playlistId", "playlist").toInt() val id = parseIdFromIntent(intent, "playlistId", "playlist").toInt()
if (id >= 0) { if (id >= 0) {
val position = intent.getIntExtra("position", 0) val position = intent.getIntExtra("position", 0)
val songs = ArrayList( val songs = ArrayList(PlaylistSongsLoader.getPlaylistSongList(this, id).blockingFirst())
PlaylistSongsLoader.getPlaylistSongList(this, id).blockingFirst())
MusicPlayerRemote.openQueue(songs, position, true) MusicPlayerRemote.openQueue(songs, position, true)
handled = true handled = true
} }
@ -164,16 +170,14 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
val id = parseIdFromIntent(intent, "albumId", "album").toInt() val id = parseIdFromIntent(intent, "albumId", "album").toInt()
if (id >= 0) { if (id >= 0) {
val position = intent.getIntExtra("position", 0) val position = intent.getIntExtra("position", 0)
MusicPlayerRemote MusicPlayerRemote.openQueue(AlbumLoader.getAlbum(this, id).blockingFirst().songs!!, position, true)
.openQueue(AlbumLoader.getAlbum(this, id).blockingFirst().songs!!, position, true)
handled = true handled = true
} }
} else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) { } else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
val id = parseIdFromIntent(intent, "artistId", "artist").toInt() val id = parseIdFromIntent(intent, "artistId", "artist").toInt()
if (id >= 0) { if (id >= 0) {
val position = intent.getIntExtra("position", 0) val position = intent.getIntExtra("position", 0)
MusicPlayerRemote MusicPlayerRemote.openQueue(ArtistLoader.getArtist(this, id).blockingFirst().songs, position, true)
.openQueue(ArtistLoader.getArtist(this, id).blockingFirst().songs, position, true)
handled = true handled = true
} }
} }
@ -192,7 +196,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
} catch (e: NumberFormatException) { } catch (e: NumberFormatException) {
Log.e(TAG, e.message) Log.e(TAG, e.message)
} }
} }
} }
return id return id
@ -213,6 +216,10 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
} }
override fun handleBackPress(): Boolean { override fun handleBackPress(): Boolean {
if (drawerLayout.isDrawerOpen(navigationView)) {
drawerLayout.closeDrawers()
return true
}
return super.handleBackPress() || currentFragment.handleBackPress() return super.handleBackPress() || currentFragment.handleBackPress()
} }
@ -257,10 +264,10 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
private fun showPromotionalOffer() { private fun showPromotionalOffer() {
MaterialDialog.Builder(this) MaterialDialog.Builder(this)
.positiveText("Buy") .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) .negativeText(android.R.string.cancel)
.customView(R.layout.dialog_promotional_offer, false) .customView(R.layout.dialog_promotional_offer, false)
.dismissListener { dialog -> .dismissListener {
PreferenceManager.getDefaultSharedPreferences(this@MainActivity) PreferenceManager.getDefaultSharedPreferences(this@MainActivity)
.edit() .edit()
.putBoolean("shown", true) .putBoolean("shown", true)
@ -269,19 +276,82 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
.show() .show()
} }
override fun onNavigationItemSelected(menuItem: MenuItem): Boolean {
PreferenceUtil.getInstance().lastPage = menuItem.itemId
selectedFragment(menuItem.itemId)
return true
}
private fun selectedFragment(itemId: Int) { private fun selectedFragment(itemId: Int) {
when (itemId) { 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_album,
R.id.action_home -> setCurrentFragment(BannerHomeFragment.newInstance(), false, BannerHomeFragment.TAG) 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 { companion object {
const val APP_INTRO_REQUEST = 2323 const val APP_INTRO_REQUEST = 2323
const val LIBRARY = 1 const val LIBRARY = 1
@ -290,5 +360,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), SharedPreferences.OnSharedP
private const val TAG = "MainActivity" private const val TAG = "MainActivity"
private const val APP_USER_INFO_REQUEST = 9003 private const val APP_USER_INFO_REQUEST = 9003
private const val REQUEST_CODE_THEME = 9002 private const val REQUEST_CODE_THEME = 9002
private const val PURCHASE_REQUEST = 101
} }
} }

View file

@ -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<Song>(), 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<Song> songs) {
adapter.swapDataSet(songs);
}
@OnClick(R.id.action_shuffle)
public void onViewClicked() {
if (adapter.getDataSet().isEmpty()) {
return;
}
MusicPlayerRemote.INSTANCE.openAndShuffleQueue(adapter.getDataSet(), true);
}
}

View file

@ -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<Song>) {
adapter.swapDataSet(songs)
}
companion object {
var EXTRA_PLAYLIST = "extra_playlist"
}
}

View file

@ -27,7 +27,7 @@ import code.name.monkey.appthemehelper.util.MaterialUtil;
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper; import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper;
import code.name.monkey.retromusic.BuildConfig; import code.name.monkey.retromusic.BuildConfig;
import code.name.monkey.retromusic.R; 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; import code.name.monkey.retromusic.ui.activities.base.AbsBaseActivity;
/** /**
@ -106,7 +106,7 @@ public class ProVersionActivity extends AbsBaseActivity implements
} }
break; break;
case R.id.purchase_button: case R.id.purchase_button:
billingProcessor.purchase(ProVersionActivity.this, RetroApplication.PRO_VERSION_PRODUCT_ID); billingProcessor.purchase(ProVersionActivity.this, App.PRO_VERSION_PRODUCT_ID);
break; break;
} }
} }
@ -119,7 +119,7 @@ public class ProVersionActivity extends AbsBaseActivity implements
@Override @Override
public void onPurchaseHistoryRestored() { public void onPurchaseHistoryRestored() {
if (RetroApplication.Companion.isProVersion()) { if (App.Companion.isProVersion()) {
Toast.makeText(this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG) Toast.makeText(this, R.string.restored_previous_purchase_please_restart, Toast.LENGTH_LONG)
.show(); .show();
setResult(RESULT_OK); setResult(RESULT_OK);

View file

@ -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();
}
}
}

View file

@ -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"
}
}

View file

@ -46,7 +46,7 @@ class WhatsNewActivity : AbsBaseActivity() {
appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this)) appBarLayout.setBackgroundColor(ThemeStore.primaryColor(this))
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
title = null title = null
toolbar.setNavigationOnClickListener({ v -> onBackPressed() }) toolbar.setNavigationOnClickListener { onBackPressed() }
whatNewtitle.setTextColor(ThemeStore.textColorPrimary(this)) whatNewtitle.setTextColor(ThemeStore.textColorPrimary(this))
ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this)) ToolbarContentTintHelper.colorBackButton(toolbar, ThemeStore.accentColor(this))

View file

@ -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);
}
}
}

View file

@ -1,7 +1,6 @@
package code.name.monkey.retromusic.ui.activities.base package code.name.monkey.retromusic.ui.activities.base
import android.Manifest import android.Manifest
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.media.AudioManager import android.media.AudioManager
@ -15,17 +14,16 @@ import androidx.core.app.ActivityCompat
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper
abstract class AbsBaseActivity : AbsThemeActivity() { abstract class AbsBaseActivity : AbsThemeActivity() {
private var hadPermissions: Boolean = false private var hadPermissions: Boolean = false
private var permissions: Array<String>? = null private lateinit var permissions: Array<String>
private var permissionDeniedMessage: String? = null private var permissionDeniedMessage: String? = null
open fun getPermissionsToRequest(): Array<String>? { open fun getPermissionsToRequest(): Array<String> {
return null return arrayOf()
} }
protected fun setPermissionDeniedMessage(message: String) { protected fun setPermissionDeniedMessage(message: String) {
@ -82,20 +80,16 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
protected fun showOverflowMenu() { protected fun showOverflowMenu() {
} }
override fun attachBaseContext(newBase: Context) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase))
}
protected open fun requestPermissions() { protected open fun requestPermissions() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(permissions!!, PERMISSION_REQUEST) requestPermissions(permissions, PERMISSION_REQUEST)
} }
} }
protected fun hasPermissions(): Boolean { protected fun hasPermissions(): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (permission in permissions!!) { for (permission in permissions) {
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) { if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
return false return false
} }

View file

@ -138,7 +138,7 @@ abstract class AbsMusicServiceActivity : AbsCastActivity(), MusicServiceEventLis
} }
override fun getPermissionsToRequest(): Array<String>? { override fun getPermissionsToRequest(): Array<String> {
return arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE) return arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)
} }
@ -163,6 +163,6 @@ abstract class AbsMusicServiceActivity : AbsCastActivity(), MusicServiceEventLis
} }
companion object { companion object {
val TAG = AbsMusicServiceActivity::class.java.simpleName val TAG: String = AbsMusicServiceActivity::class.java.simpleName
} }
} }

View file

@ -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.base.AbsPlayerFragment
import code.name.monkey.retromusic.ui.fragments.player.adaptive.AdaptiveFragment 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.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.util.PreferenceUtil
import code.name.monkey.retromusic.views.BottomNavigationBarTinted import code.name.monkey.retromusic.views.BottomNavigationBarTinted
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
@ -58,7 +62,7 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
slidingUpPanelLayout = findViewById(R.id.sliding_layout); slidingUpPanelLayout = findViewById(R.id.sliding_layout);
bottomNavigationView = findViewById(R.id.bottom_navigation); bottomNavigationView = findViewById(R.id.bottom_navigation);
choosFragmentForTheme() chooseFragmentForTheme()
setupSlidingUpPanel() setupSlidingUpPanel()
} }
@ -207,22 +211,23 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
miniPlayerFragment!!.view!!.visibility = if (alpha == 0f) View.GONE else View.VISIBLE miniPlayerFragment!!.view!!.visibility = if (alpha == 0f) View.GONE else View.VISIBLE
} }
private fun choosFragmentForTheme() { private fun chooseFragmentForTheme() {
currentNowPlayingScreen = PreferenceUtil.getInstance().nowPlayingScreen currentNowPlayingScreen = PreferenceUtil.getInstance().nowPlayingScreen
val fragment: Fragment // must implement AbsPlayerFragment val fragment: Fragment = when (currentNowPlayingScreen) {
when (currentNowPlayingScreen) { NowPlayingScreen.BLUR -> BlurPlayerFragment()
NowPlayingScreen.BLUR -> fragment = BlurPlayerFragment() NowPlayingScreen.ADAPTIVE -> AdaptiveFragment()
NowPlayingScreen.ADAPTIVE -> fragment = AdaptiveFragment() NowPlayingScreen.NORMAL -> PlayerFragment()
else -> fragment = AdaptiveFragment() 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.beginTransaction().replace(R.id.player_fragment_container, fragment).commit()
supportFragmentManager.executePendingTransactions() supportFragmentManager.executePendingTransactions()
playerFragment = supportFragmentManager.findFragmentById(R.id.player_fragment_container) as AbsPlayerFragment? playerFragment = supportFragmentManager.findFragmentById(R.id.player_fragment_container) as AbsPlayerFragment
miniPlayerFragment = supportFragmentManager.findFragmentById(R.id.mini_player_fragment) as MiniPlayerFragment? miniPlayerFragment = supportFragmentManager.findFragmentById(R.id.mini_player_fragment) as MiniPlayerFragment
miniPlayerFragment!!.view!!.setOnClickListener { expandPanel() } miniPlayerFragment!!.view!!.setOnClickListener { expandPanel() }
} }
@ -296,6 +301,6 @@ abstract class AbsSlidingMusicPanelActivity protected constructor() : AbsMusicSe
companion object { companion object {
val TAG = AbsSlidingMusicPanelActivity::class.java.simpleName val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
} }
} }

View file

@ -96,15 +96,16 @@ abstract class AbsThemeActivity : ATHActivity(), Runnable {
if (VersionUtils.hasKitKat()) { if (VersionUtils.hasKitKat()) {
val statusBar = window.decorView.rootView.findViewById<View>(R.id.status_bar) val statusBar = window.decorView.rootView.findViewById<View>(R.id.status_bar)
if (statusBar != null) { if (statusBar != null) {
if (VersionUtils.hasMarshmallow()) { when {
window.statusBarColor = color VersionUtils.hasMarshmallow() -> window.statusBarColor = color
} else if (VersionUtils.hasLollipop()) { VersionUtils.hasLollipop() -> statusBar.setBackgroundColor(ColorUtil.darkenColor(color))
statusBar.setBackgroundColor(ColorUtil.darkenColor(color)) else -> statusBar.setBackgroundColor(color)
} else {
statusBar.setBackgroundColor(color)
} }
} else if (Build.VERSION.SDK_INT >= 21) { } 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) setLightStatusbarAuto(color)

View file

@ -70,8 +70,7 @@ public class CollageSongAdapter extends RecyclerView.Adapter<CollageSongViewHold
class CollageSongViewHolder extends MediaEntryViewHolder { class CollageSongViewHolder extends MediaEntryViewHolder {
@BindViews({R.id.image_2, R.id.image_3, R.id.image_4, R.id.image_5, R.id.image_6, @BindViews({R.id.image_2, R.id.image_3, R.id.image_4, R.id.image_5, R.id.image_6, R.id.image_7, R.id.image_8, R.id.image_9})
R.id.image_7, R.id.image_8, R.id.image_9})
@Nullable @Nullable
List<ImageView> imageViews; List<ImageView> imageViews;
@ -80,14 +79,12 @@ public class CollageSongAdapter extends RecyclerView.Adapter<CollageSongViewHold
CollageSongViewHolder(View itemView) { CollageSongViewHolder(View itemView) {
super(itemView); super(itemView);
ButterKnife.bind(this, itemView); //ButterKnife.bind(this, itemView);
Context context = itemView.getContext(); //Context context = itemView.getContext();
int color = ThemeStore.accentColor(context); //int color = ThemeStore.accentColor(context);
view.setOnClickListener(v -> { //view.setOnClickListener(v -> MusicPlayerRemote.INSTANCE.openQueue(dataSet, 0, true));
MusicPlayerRemote.INSTANCE.openQueue(dataSet, 0, true); //view.setBackgroundColor(color);
}); //view.setTextColor(MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color)));
view.setBackgroundColor(color);
view.setTextColor(MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color)));
} }
void bindSongs() { void bindSongs() {

View file

@ -61,7 +61,7 @@ abstract class AbsOffsetSongAdapter : SongAdapter {
override// could also return null, just to be safe return empty song override// could also return null, just to be safe return empty song
val song: 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?) { override fun onClick(v: View?) {
if (isInQuickSelectMode && itemViewType != OFFSET_ITEM) { if (isInQuickSelectMode && itemViewType != OFFSET_ITEM) {

View file

@ -36,7 +36,7 @@ class OrderablePlaylistSongAdapter(activity: AppCompatActivity,
positionFinal-- positionFinal--
var long: Long = 0 var long: Long = 0
if (position < 0) { if (positionFinal < 0) {
long = -2 long = -2
} else { } else {
if (dataSet[positionFinal] is PlaylistSong) { if (dataSet[positionFinal] is PlaylistSong) {

View file

@ -10,7 +10,6 @@ import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan import android.text.style.ForegroundColorSpan
import android.view.* import android.view.*
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
import butterknife.OnClick
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -76,7 +75,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(), MusicProgressViewUpda
private fun updateSongTitle() { private fun updateSongTitle() {
val builder = SpannableStringBuilder() val builder = SpannableStringBuilder()
val song = MusicPlayerRemote.currentSong ?: return val song = MusicPlayerRemote.currentSong
val title = SpannableString(song.title) val title = SpannableString(song.title)
title.setSpan(ForegroundColorSpan(ThemeStore.textColorPrimary(context!!)), 0, title.length, 0) title.setSpan(ForegroundColorSpan(ThemeStore.textColorPrimary(context!!)), 0, title.length, 0)

View file

@ -6,9 +6,19 @@ import code.name.monkey.retromusic.R;
public enum NowPlayingScreen { 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), 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 @StringRes
public final int titleRes; public final int titleRes;

View file

@ -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();
}
}

View file

@ -47,19 +47,19 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
val audioManager = audioManager val audioManager = audioManager
if (audioManager != null) { if (audioManager != null) {
volumeSeekBar!!.max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) volumeSeekBar.max = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
volumeSeekBar!!.progress = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) volumeSeekBar.progress = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC)
} }
volumeSeekBar!!.setOnSeekBarChangeListener(this) volumeSeekBar.setOnSeekBarChangeListener(this)
} }
override fun onAudioVolumeChanged(currentVolume: Int, maxVolume: Int) { override fun onAudioVolumeChanged(currentVolume: Int, maxVolume: Int) {
if (volumeSeekBar == null) { if (volumeSeekBar == null) {
return return
} }
volumeSeekBar!!.max = maxVolume volumeSeekBar.max = maxVolume
volumeSeekBar!!.progress = currentVolume volumeSeekBar.progress = currentVolume
volumeDown!!.setImageResource(if (currentVolume == 0) R.drawable.ic_volume_off_white_24dp else R.drawable.ic_volume_down_white_24dp) volumeDown.setImageResource(if (currentVolume == 0) R.drawable.ic_volume_off_white_24dp else R.drawable.ic_volume_down_white_24dp)
} }
override fun onDestroyView() { override fun onDestroyView() {
@ -98,9 +98,9 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
} }
private fun setProgressBarColor(newColor: Int) { private fun setProgressBarColor(newColor: Int) {
TintHelper.setTintAuto(volumeSeekBar!!, newColor, false) TintHelper.setTintAuto(volumeSeekBar, newColor, false)
volumeDown!!.setColorFilter(newColor, PorterDuff.Mode.SRC_IN) volumeDown.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
volumeUp!!.setColorFilter(newColor, PorterDuff.Mode.SRC_IN) volumeUp.setColorFilter(newColor, PorterDuff.Mode.SRC_IN)
} }
private fun setTintable(color: Int) { private fun setTintable(color: Int) {
@ -108,7 +108,7 @@ class VolumeFragment : Fragment(), SeekBar.OnSeekBarChangeListener, OnAudioVolum
} }
fun removeThumb() { fun removeThumb() {
volumeSeekBar!!.thumb = null volumeSeekBar.thumb = null
} }
private fun setPauseWhenZeroVolume(pauseWhenZeroVolume: Boolean) { private fun setPauseWhenZeroVolume(pauseWhenZeroVolume: Boolean) {

View file

@ -55,7 +55,7 @@ abstract class AbsPlayerControlsFragment : AbsMusicServiceFragment(), MusicProgr
} }
var prevButton: ImageButton? = null /* var prevButton: ImageButton? = null
var nextButton: ImageButton? = null var nextButton: ImageButton? = null
var repeatButton: ImageButton? = null var repeatButton: ImageButton? = null
var shuffleButton: ImageButton? = null var shuffleButton: ImageButton? = null
@ -63,11 +63,12 @@ abstract class AbsPlayerControlsFragment : AbsMusicServiceFragment(), MusicProgr
var songTotalTime: TextView? = null var songTotalTime: TextView? = null
var songCurrentProgress: TextView? = null var songCurrentProgress: TextView? = null
var volumeContainer: View? = null var volumeContainer: View? = null
var playPauseFab: ImageButton? = null var playPauseFab: ImageButton? = null*/
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) 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) prevButton = view.findViewById(R.id.player_prev_button)
nextButton = view.findViewById(R.id.player_next_button) nextButton = view.findViewById(R.id.player_next_button)
repeatButton = view.findViewById(R.id.player_repeat_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) progressSlider = view.findViewById(R.id.player_progress_slider)
songTotalTime = view.findViewById(R.id.player_song_total_time) songTotalTime = view.findViewById(R.id.player_song_total_time)
songCurrentProgress = view.findViewById(R.id.player_song_current_progress) 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)*/
} }
} }

View file

@ -32,8 +32,6 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem
private set private set
private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null
protected var toolbar: Toolbar? = null
override fun onAttach(context: Context?) { override fun onAttach(context: Context?) {
super.onAttach(context) super.onAttach(context)
@ -146,6 +144,8 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem
MusicUtil.toggleFavorite(activity!!, song) MusicUtil.toggleFavorite(activity!!, song)
} }
abstract fun toolbarGet(): Toolbar
abstract fun onShow() abstract fun onShow()
abstract fun onHide() abstract fun onHide()
@ -193,7 +193,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem
else else
R.drawable.ic_favorite_border_white_24dp R.drawable.ic_favorite_border_white_24dp
val drawable = RetroUtil.getTintedVectorDrawable(activity, res, toolbarIconColor()) 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) }.execute(MusicPlayerRemote.currentSong)

View file

@ -1,12 +1,9 @@
package code.name.monkey.retromusic.ui.fragments.mainactivity package code.name.monkey.retromusic.ui.fragments.mainactivity
import android.os.Bundle import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import androidx.recyclerview.widget.LinearLayoutManager
import java.util.ArrayList
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.mvp.contract.GenreContract 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.adapter.GenreAdapter
import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewFragment import code.name.monkey.retromusic.ui.fragments.base.AbsLibraryPagerRecyclerViewFragment
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import java.util.*
class GenreFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(), GenreContract.GenreView { class GenreFragment : AbsLibraryPagerRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(), GenreContract.GenreView {

View file

@ -7,7 +7,6 @@ import android.widget.TextView
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import butterknife.Unbinder
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.common.ATHToolbarActivity import code.name.monkey.appthemehelper.common.ATHToolbarActivity
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
@ -109,10 +108,7 @@ class LibraryFragment : AbsMainActivityFragment(), CabHolder, MainActivityFragme
appbar.addOnOffsetChangedListener(this) appbar.addOnOffsetChangedListener(this)
mainActivity.title = null mainActivity.title = null
mainActivity.setSupportActionBar(toolbar) mainActivity.setSupportActionBar(toolbar)
toolbar.navigationIcon = RetroUtil.getTintedDrawable(mainActivity, R.drawable.ic_menu_white_24dp, ThemeStore.textColorPrimary(mainActivity))
toolbar.setNavigationOnClickListener { NavigationUtil.goToSearch(mainActivity) }
toolbar.setOnClickListener { showMainMenu() }
toolbar.navigationIcon = RetroUtil.getTintedDrawable(mainActivity, R.drawable.ic_search_white_24dp, ThemeStore.textColorPrimary(mainActivity))
} }

View file

@ -40,7 +40,6 @@ import androidx.loader.app.LoaderManager;
import androidx.loader.content.Loader; import androidx.loader.content.Loader;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.Unbinder; import butterknife.Unbinder;
import code.name.monkey.appthemehelper.ThemeStore; import code.name.monkey.appthemehelper.ThemeStore;
@ -74,8 +73,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
AppBarLayout.OnOffsetChangedListener, LoaderManager.LoaderCallbacks<List<File>> { AppBarLayout.OnOffsetChangedListener, LoaderManager.LoaderCallbacks<List<File>> {
public static final String TAG = FoldersFragment.class.getSimpleName(); 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, "audio/*", MimeTypeMap.getSingleton()) ||
FileUtil.fileIsMimeType(file, "application/opus", MimeTypeMap.getSingleton()) || FileUtil.fileIsMimeType(file, "application/opus", MimeTypeMap.getSingleton()) ||
FileUtil.fileIsMimeType(file, "application/ogg", 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 PATH = "path";
private static final String CRUMBS = "crumbs"; private static final String CRUMBS = "crumbs";
private static final int LOADER_ID = LoaderIds.Companion.getFOLDERS_FRAGMENT(); private static final int LOADER_ID = LoaderIds.Companion.getFOLDERS_FRAGMENT();
@BindView(R.id.coordinator_layout)
View coordinatorLayout;
@BindView(R.id.container) private View coordinatorLayout, container, empty;
View container;
@BindView(R.id.title) private TextView title;
TextView title;
@BindView(android.R.id.empty) private Toolbar toolbar;
View empty;
@BindView(R.id.toolbar) private BreadCrumbLayout breadCrumbs;
Toolbar toolbar;
@BindView(R.id.bread_crumbs) private AppBarLayout appBarLayout;
BreadCrumbLayout breadCrumbs;
@BindView(R.id.app_bar)
AppBarLayout appbar;
@BindView(R.id.recycler_view)
FastScrollRecyclerView recyclerView;
private FastScrollRecyclerView recyclerView;
private Comparator<File> fileComparator = (lhs, rhs) -> { private Comparator<File> fileComparator = (lhs, rhs) -> {
if (lhs.isDirectory() && !rhs.isDirectory()) { if (lhs.isDirectory() && !rhs.isDirectory()) {
@ -118,10 +104,8 @@ public class FoldersFragment extends AbsMainActivityFragment implements
(rhs.getName()); (rhs.getName());
} }
}; };
private Unbinder unbinder;
private SongFileAdapter adapter; private SongFileAdapter adapter;
private MaterialCab cab; private MaterialCab cab;
public FoldersFragment() { 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) { private void setCrumb(BreadCrumbLayout.Crumb crumb, boolean addToHistory) {
if (crumb == null) { if (crumb == null) {
return; return;
@ -215,15 +210,13 @@ public class FoldersFragment extends AbsMainActivityFragment implements
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_folder, container, false); View view = inflater.inflate(R.layout.fragment_folder, container, false);
unbinder = ButterKnife.bind(this, view); initViews(view);
return view; return view;
} }
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
setStatusbarColorAuto(view); setStatusbarColorAuto(view);
//getMainActivity().getSlidingUpPanelLayout().setShadowHeight(0);
setUpAppbarColor(); setUpAppbarColor();
setUpBreadCrumbs(); setUpBreadCrumbs();
setUpRecyclerView(); setUpRecyclerView();
@ -238,18 +231,17 @@ public class FoldersFragment extends AbsMainActivityFragment implements
int primaryColor = ThemeStore.primaryColor(getContext()); int primaryColor = ThemeStore.primaryColor(getContext());
toolbar.setNavigationIcon(R.drawable.ic_keyboard_backspace_black_24dp); toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
//noinspection ConstantConditions //noinspection ConstantConditions
getActivity().setTitle(null); getActivity().setTitle(null);
getMainActivity().setSupportActionBar(toolbar); getMainActivity().setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(v -> getActivity().onBackPressed());
TintHelper.setTintAuto(container, primaryColor, true); TintHelper.setTintAuto(container, primaryColor, true);
appbar.setBackgroundColor(primaryColor); appBarLayout.setBackgroundColor(primaryColor);
toolbar.setBackgroundColor(primaryColor); toolbar.setBackgroundColor(primaryColor);
breadCrumbs.setActivatedContentColor(ToolbarContentTintHelper.toolbarTitleColor(getActivity(), ColorUtil.darkenColor(primaryColor))); breadCrumbs.setActivatedContentColor(ToolbarContentTintHelper.toolbarTitleColor(getActivity(), ColorUtil.darkenColor(primaryColor)));
breadCrumbs.setDeactivatedContentColor(ToolbarContentTintHelper.toolbarSubtitleColor(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() { private void setUpBreadCrumbs() {
@ -261,7 +253,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
ViewUtil.setUpFastScrollRecyclerViewColor(getActivity(), recyclerView, ViewUtil.setUpFastScrollRecyclerViewColor(getActivity(), recyclerView,
ThemeStore.accentColor(getActivity())); ThemeStore.accentColor(getActivity()));
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
appbar.addOnOffsetChangedListener(this); appBarLayout.addOnOffsetChangedListener(this);
} }
private void setUpAdapter() { private void setUpAdapter() {
@ -286,8 +278,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
@Override @Override
public void onDestroyView() { public void onDestroyView() {
appbar.removeOnOffsetChangedListener(this); appBarLayout.removeOnOffsetChangedListener(this);
unbinder.unbind();
super.onDestroyView(); super.onDestroyView();
} }
@ -473,7 +464,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
@Override @Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) { public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
container.setPadding(container.getPaddingLeft(), container.getPaddingTop(), container.setPadding(container.getPaddingLeft(), container.getPaddingTop(),
container.getPaddingRight(), appbar.getTotalScrollRange() + verticalOffset); container.getPaddingRight(), this.appBarLayout.getTotalScrollRange() + verticalOffset);
} }
private void checkIsEmpty() { private void checkIsEmpty() {

View file

@ -1,18 +1,19 @@
package code.name.monkey.retromusic.ui.fragments.mainactivity.home package code.name.monkey.retromusic.ui.fragments.mainactivity.home
import android.graphics.Bitmap import android.graphics.Bitmap
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.util.DisplayMetrics import android.util.DisplayMetrics
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import android.widget.ImageView
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import butterknife.OnClick
import code.name.monkey.appthemehelper.ThemeStore 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_BANNER
import code.name.monkey.retromusic.Constants.USER_PROFILE import code.name.monkey.retromusic.Constants.USER_PROFILE
import code.name.monkey.retromusic.R 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.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil 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.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.DiskCacheStrategy
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers 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.io.File
import java.util.* import java.util.*
class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallbacks, HomeContract.HomeView { 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?, override fun onActivityCreated(savedInstanceState: Bundle?) {
savedInstanceState: Bundle?): View? { super.onActivityCreated(savedInstanceState)
val view = inflater.inflate(if (PreferenceUtil.getInstance().isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home, viewGroup, false) mainActivity.setBottomBarVisibility(View.GONE)
}
if (!PreferenceUtil.getInstance().isHomeBanner)
setStatusbarColorAuto(view) 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)
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
} }
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 private val displayMetrics: DisplayMetrics
get() { get() {
@ -122,16 +80,12 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
val timeOfDay = c.get(Calendar.HOUR_OF_DAY) val timeOfDay = c.get(Calendar.HOUR_OF_DAY)
var images = arrayOf<String>() var images = arrayOf<String>()
if (timeOfDay in 0..5) { when (timeOfDay) {
images = resources.getStringArray(R.array.night) in 0..5 -> images = resources.getStringArray(R.array.night)
} else if (timeOfDay in 6..11) { in 6..11 -> images = resources.getStringArray(R.array.morning)
images = resources.getStringArray(R.array.morning) in 12..15 -> images = resources.getStringArray(R.array.after_noon)
} else if (timeOfDay in 12..15) { in 16..19 -> images = resources.getStringArray(R.array.evening)
images = resources.getStringArray(R.array.after_noon) in 20..23 -> images = resources.getStringArray(R.array.night)
} else if (timeOfDay in 16..19) {
images = resources.getStringArray(R.array.evening)
} else if (timeOfDay in 20..23) {
images = resources.getStringArray(R.array.night)
} }
val day = images[Random().nextInt(images.size)] val day = images[Random().nextInt(images.size)]
@ -141,47 +95,39 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
private fun loadTimeImage(day: String) { private fun loadTimeImage(day: String) {
if (imageView != null) { if (bannerImage != null) {
if (PreferenceUtil.getInstance().bannerImage.isEmpty()) { if (PreferenceUtil.getInstance().bannerImage.isEmpty()) {
Glide.with(activity).load(day) Glide.with(activity).load(day)
.asBitmap() .asBitmap()
.placeholder(R.drawable.material_design_default) .placeholder(R.drawable.material_design_default)
.diskCacheStrategy(DiskCacheStrategy.SOURCE) .diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(imageView!!) .into(bannerImage!!)
} else { } 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) { private fun loadImageFromStorage(imageView: ImageView) {
disposable.add(Compressor(context!!) disposable.add(Compressor(context!!)
.setMaxHeight(300) .setMaxHeight(300)
.setMaxWidth(300) .setMaxWidth(300)
.setQuality(75) .setQuality(75)
.setCompressFormat(Bitmap.CompressFormat.WEBP) .setCompressFormat(Bitmap.CompressFormat.WEBP)
.compressToBitmapAsFlowable( .compressToBitmapAsFlowable(File(PreferenceUtil.getInstance().profileImage, USER_PROFILE))
File(PreferenceUtil.getInstance().profileImage, USER_PROFILE))
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread()) .observeOn(AndroidSchedulers.mainThread())
.subscribe({ .subscribe({
imageView.setImageBitmap(it) imageView.setImageBitmap(it)
}) { }) {
imageView.setImageDrawable(ContextCompat imageView.setImageDrawable(ContextCompat.getDrawable(context!!, R.drawable.ic_person_flat))
.getDrawable(context!!, R.drawable.ic_person_flat))
}) })
} }
@ -193,20 +139,55 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) 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() setupToolbar()
loadImageFromStorage(userImage)
homePresenter.subscribe() homePresenter.subscribe()
loadImageFromStorage(userImage)
getTimeOfTheDay() getTimeOfTheDay()
} }
private fun setupToolbar() { private fun setupToolbar() {
userImage.setOnClickListener { showMainMenu() } toolbar.navigationIcon = TintHelper.createTintedDrawable(ContextCompat.getDrawable(context!!, R.drawable.ic_menu_white_24dp), ThemeStore.textColorPrimary(context!!))
contentContainer.setBackgroundColor(ThemeStore.primaryColor(mainActivity)) mainActivity.title = null
} mainActivity.setSupportActionBar(toolbar)
toolbar.setBackgroundColor(Color.TRANSPARENT)
@OnClick(R.id.searchIcon)
internal fun search() {
NavigationUtil.goToSearch(mainActivity)
} }
override fun handleBackPress(): Boolean { override fun handleBackPress(): Boolean {
@ -237,41 +218,46 @@ class BannerHomeFragment : AbsMainActivityFragment(), MainActivityFragmentCallba
override fun recentArtist(artists: ArrayList<Artist>) { override fun recentArtist(artists: ArrayList<Artist>) {
recentArtistContainer.visibility = View.VISIBLE recentArtistContainer.visibility = View.VISIBLE
recentArtistRV.layoutManager = GridLayoutManager(mainActivity, 1, GridLayoutManager.HORIZONTAL, false) recentArtist.apply {
val artistAdapter = ArtistAdapter(mainActivity, artists, PreferenceUtil.getInstance().getHomeGridStyle(context!!), false, null) val artistAdapter = ArtistAdapter(mainActivity, artists, PreferenceUtil.getInstance().getHomeGridStyle(context!!), false, null)
recentArtistRV.adapter = artistAdapter layoutManager = GridLayoutManager(mainActivity, 1, GridLayoutManager.HORIZONTAL, false)
adapter = artistAdapter
}
} }
override fun recentAlbum(albums: ArrayList<Album>) { override fun recentAlbum(albums: ArrayList<Album>) {
recentAlbumsContainer.visibility = View.VISIBLE recentAlbumsContainer.visibility = View.VISIBLE
val artistAdapter = AlbumFullWithAdapter(mainActivity, val artistAdapter = AlbumFullWithAdapter(mainActivity, displayMetrics)
displayMetrics)
artistAdapter.swapData(albums) artistAdapter.swapData(albums)
recentAlbumRV.adapter = artistAdapter recentAlbum.adapter = artistAdapter
} }
override fun topArtists(artists: ArrayList<Artist>) { override fun topArtists(artists: ArrayList<Artist>) {
topArtistContainer.visibility = View.VISIBLE topArtistContainer.visibility = View.VISIBLE
topArtistRV.layoutManager = GridLayoutManager(mainActivity, 1, GridLayoutManager.HORIZONTAL, false) topArtist.apply {
val artistAdapter = ArtistAdapter(mainActivity, artists, PreferenceUtil.getInstance().getHomeGridStyle(context!!), false, null) layoutManager = GridLayoutManager(mainActivity, 1, GridLayoutManager.HORIZONTAL, false)
topArtistRV.adapter = artistAdapter val artistAdapter = ArtistAdapter(mainActivity, artists, PreferenceUtil.getInstance().getHomeGridStyle(context!!), false, null)
adapter = artistAdapter
}
} }
override fun topAlbums(albums: ArrayList<Album>) { override fun topAlbums(albums: ArrayList<Album>) {
topAlbumContainer.visibility = View.VISIBLE topAlbumsContainer.visibility = View.VISIBLE
val artistAdapter = AlbumFullWithAdapter(mainActivity, val artistAdapter = AlbumFullWithAdapter(mainActivity,
displayMetrics) displayMetrics)
artistAdapter.swapData(albums) artistAdapter.swapData(albums)
topAlbumRV.adapter = artistAdapter topAlbum.adapter = artistAdapter
} }
override fun suggestions(songs: ArrayList<Song>) { override fun suggestions(songs: ArrayList<Song>) {
if (!songs.isEmpty()) { if (!songs.isEmpty()) {
suggestionsContainer.visibility = View.VISIBLE suggestionContainer.visibility = View.VISIBLE
val artistAdapter = CollageSongAdapter(mainActivity, songs) val artistAdapter = CollageSongAdapter(mainActivity, songs)
suggestionsSongs.layoutManager = if (RetroUtil.isTablet()) GridLayoutManager(mainActivity, 2) else LinearLayoutManager(mainActivity) suggestionSongs.apply {
suggestionsSongs.adapter = artistAdapter 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<Genre>) { override fun geners(genres: ArrayList<Genre>) {
genreContainer.visibility = View.VISIBLE genreContainer.visibility = View.VISIBLE
genresRecyclerView.layoutManager = LinearLayoutManager(context) genresRecyclerView.apply {
val genreAdapter = GenreAdapter(activity!!, genres, R.layout.item_list)
val genreAdapter = GenreAdapter(activity!!, genres, R.layout.item_list) layoutManager = LinearLayoutManager(context)
genresRecyclerView.adapter = genreAdapter adapter = genreAdapter
}
} }

View file

@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import butterknife.Unbinder
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.transform.ParallaxPagerTransformer import code.name.monkey.retromusic.transform.ParallaxPagerTransformer

View file

@ -4,6 +4,7 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper 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.model.Song
import code.name.monkey.retromusic.ui.fragments.base.AbsPlayerFragment 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.PlayerAlbumCoverFragment
import kotlinx.android.synthetic.main.fragment_adaptive_player.*
class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks { class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
override fun toolbarGet(): Toolbar {
return playerToolbar
}
private var lastColor: Int = 0 private var lastColor: Int = 0
lateinit var playbackControlsFragment: AdaptivePlaybackControlsFragment private lateinit var playbackControlsFragment: AdaptivePlaybackControlsFragment
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_adaptive_player, container, false); return inflater.inflate(R.layout.fragment_adaptive_player, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
toolbar = view.findViewById(R.id.toolbar)
setUpSubFragments() setUpSubFragments()
setUpPlayerToolbar() setUpPlayerToolbar()
} }
@ -31,19 +36,21 @@ class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks
private fun setUpSubFragments() { private fun setUpSubFragments() {
playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playback_controls_fragment) as AdaptivePlaybackControlsFragment playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playback_controls_fragment) as AdaptivePlaybackControlsFragment
val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.player_album_cover_fragment) as PlayerAlbumCoverFragment val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.player_album_cover_fragment) as PlayerAlbumCoverFragment
playerAlbumCoverFragment.setCallbacks(this) playerAlbumCoverFragment.apply {
playerAlbumCoverFragment.removeSlideEffect() removeSlideEffect()
}.setCallbacks(this)
} }
private fun setUpPlayerToolbar() { private fun setUpPlayerToolbar() {
val primaryColor = ATHUtil.resolveColor(context, R.attr.iconColor) ATHUtil.resolveColor(context, R.attr.iconColor)
/*toolbar!!.apply { val primaryColor = ThemeStore.primaryColor(context!!)
playerToolbar.apply {
inflateMenu(R.menu.menu_player) inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { activity!!.onBackPressed() } setNavigationOnClickListener { activity!!.onBackPressed() }
ToolbarContentTintHelper.colorizeToolbar(this, primaryColor, activity) ToolbarContentTintHelper.colorizeToolbar(this, primaryColor, activity)
setTitleTextColor(primaryColor) setTitleTextColor(primaryColor)
setSubtitleTextColor(ThemeStore.textColorSecondary(context!!)) setSubtitleTextColor(ThemeStore.textColorSecondary(context!!))
}.setOnMenuItemClickListener(this)*/ }.setOnMenuItemClickListener(this)
} }
override fun onServiceConnected() { override fun onServiceConnected() {
@ -59,10 +66,10 @@ class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks
private fun updateSong() { private fun updateSong() {
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
/*toolbar!!.apply { playerToolbar.apply {
title = song.title title = song.title
subtitle = song.artistName subtitle = song.artistName
}*/ }
} }
override fun toggleFavorite(song: Song) { override fun toggleFavorite(song: Song) {
@ -80,7 +87,7 @@ class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks
playbackControlsFragment.setDark(color) playbackControlsFragment.setDark(color)
lastColor = color lastColor = color
callbacks!!.onPaletteColorChanged() 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() { override fun onShow() {

View file

@ -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.ui.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil 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() { class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
private val playPauseDrawable: PlayPauseDrawable? = null
private var lastPlaybackControlsColor: Int = 0 private var lastPlaybackControlsColor: Int = 0
private var lastDisabledPlaybackControlsColor: Int = 0 private var lastDisabledPlaybackControlsColor: Int = 0
private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
@ -45,13 +44,13 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
setUpMusicControllers() setUpMusicControllers()
hideVolumeIfAvailable() hideVolumeIfAvailable()
playPauseFab!!.setOnClickListener { playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) { if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.pauseSong() MusicPlayerRemote.pauseSong()
} else { } else {
MusicPlayerRemote.resumePlaying() MusicPlayerRemote.resumePlaying()
} }
showBouceAnimation(playPauseFab!!) showBouceAnimation(playPauseButton)
} }
} }
@ -97,9 +96,9 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
updatePrevNextColor() updatePrevNextColor()
updatePlayPauseColor() updatePlayPauseColor()
TintHelper.setTintAuto(playPauseFab!!, MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color)), false) TintHelper.setTintAuto(playPauseButton, MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color)), false)
TintHelper.setTintAuto(playPauseFab!!, color, true) TintHelper.setTintAuto(playPauseButton, color, true)
TintHelper.setTintAuto(progressSlider!!, color, false) TintHelper.setTintAuto(progressSlider, color, false)
} }
private fun updatePlayPauseColor() { private fun updatePlayPauseColor() {
@ -107,18 +106,17 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
} }
private fun setUpPlayPauseFab() { private fun setUpPlayPauseFab() {
playPauseFab!!.setOnClickListener(PlayPauseButtonOnClickHandler()) playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
} }
protected fun updatePlayPauseDrawableState() { private fun updatePlayPauseDrawableState() {
if (MusicPlayerRemote.isPlaying) { if (MusicPlayerRemote.isPlaying) {
playPauseFab!!.setImageResource(R.drawable.ic_pause_white_24dp) playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
} else { } else {
playPauseFab!!.setImageResource(R.drawable.ic_play_arrow_white_24dp) playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
} }
} }
private fun setUpMusicControllers() { private fun setUpMusicControllers() {
setUpPlayPauseFab() setUpPlayPauseFab()
setUpPrevNext() setUpPrevNext()
@ -129,47 +127,62 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
private fun setUpPrevNext() { private fun setUpPrevNext() {
updatePrevNextColor() updatePrevNextColor()
nextButton!!.setOnClickListener { MusicPlayerRemote.playNextSong() } nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
prevButton!!.setOnClickListener { MusicPlayerRemote.back() } previousButton.setOnClickListener { MusicPlayerRemote.back() }
} }
private fun updatePrevNextColor() { private fun updatePrevNextColor() {
nextButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
prevButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
private fun setUpShuffleButton() { private fun setUpShuffleButton() {
shuffleButton!!.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() } shuffleButton.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() }
} }
override fun updateShuffleState() { override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) { when (MusicPlayerRemote.shuffleMode) {
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
else -> shuffleButton!!.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN) else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
} }
private fun setUpRepeatButton() { private fun setUpRepeatButton() {
repeatButton!!.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() } repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
} }
override fun updateRepeatState() { override fun updateRepeatState() {
when (MusicPlayerRemote.repeatMode) { when (MusicPlayerRemote.repeatMode) {
MusicService.REPEAT_MODE_NONE -> { MusicService.REPEAT_MODE_NONE -> {
repeatButton!!.setImageResource(R.drawable.ic_repeat_white_24dp) repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
repeatButton!!.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN) repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
MusicService.REPEAT_MODE_ALL -> { MusicService.REPEAT_MODE_ALL -> {
repeatButton!!.setImageResource(R.drawable.ic_repeat_white_24dp) repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
repeatButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
MusicService.REPEAT_MODE_THIS -> { MusicService.REPEAT_MODE_THIS -> {
repeatButton!!.setImageResource(R.drawable.ic_repeat_one_white_24dp) repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp)
repeatButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) 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() { public override fun show() {
//Ignore //Ignore
@ -180,7 +193,7 @@ class AdaptivePlaybackControlsFragment : AbsPlayerControlsFragment() {
} }
override fun setUpProgressSlider() { override fun setUpProgressSlider() {
progressSlider!!.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() { progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) { if (fromUser) {
MusicPlayerRemote.seekTo(progress) 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
}
} }

View file

@ -3,19 +3,23 @@ package code.name.monkey.retromusic.ui.fragments.player.blur
import android.animation.ObjectAnimator import android.animation.ObjectAnimator
import android.graphics.Color import android.graphics.Color
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.graphics.drawable.ClipDrawable
import android.graphics.drawable.LayerDrawable
import android.os.Bundle import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator import android.view.animation.DecelerateInterpolator
import android.view.animation.LinearInterpolator import android.view.animation.LinearInterpolator
import android.widget.SeekBar import android.widget.SeekBar
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.widget.AppCompatTextView import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import butterknife.BindView import code.name.monkey.appthemehelper.ThemeStore
import butterknife.ButterKnife import code.name.monkey.appthemehelper.util.ATHUtil
import butterknife.Unbinder 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.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.helper.MusicPlayerRemote 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.ui.fragments.base.AbsPlayerControlsFragment
import code.name.monkey.retromusic.util.MusicUtil import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil 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() { class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
lateinit var songTitle: AppCompatTextView
lateinit var text: TextView
private var lastPlaybackControlsColor: Int = 0 private var lastPlaybackControlsColor: Int = 0
private var lastDisabledPlaybackControlsColor: Int = 0 private var lastDisabledPlaybackControlsColor: Int = 0
private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null private var progressViewUpdateHelper: MusicProgressViewUpdateHelper? = null
@ -43,27 +48,35 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this) progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
} }
override fun onCreateView(inflater: LayoutInflater, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.fragment_blur_playback_controls, container, false)
songTitle = view.findViewById(R.id.title) return inflater.inflate(R.layout.fragment_player_playback_controls, container, false)
text = view.findViewById(R.id.text)
return view
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
setUpMusicControllers() setUpMusicControllers()
volumeContainer!!.visibility = if (PreferenceUtil.getInstance().volumeToggle) View.VISIBLE else View.GONE if (PreferenceUtil.getInstance().volumeToggle) {
val mVolumeFragment = childFragmentManager.findFragmentById(R.id.volume_fragment) as VolumeFragment volumeFragmentContainer.visibility = View.VISIBLE
mVolumeFragment.tintWhiteColor() } else {
volumeFragmentContainer.visibility = View.GONE
}
playPauseButton.setOnClickListener {
if (MusicPlayerRemote.isPlaying) {
MusicPlayerRemote.pauseSong()
} else {
MusicPlayerRemote.resumePlaying()
}
showBonceAnimation()
}
} }
private fun updateSong() { private fun updateSong() {
val song = MusicPlayerRemote.currentSong val song = MusicPlayerRemote.currentSong
songTitle.text = song.title title.text = song.title
text.text = song.artistName text.text = song.artistName
} }
@ -102,41 +115,50 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
} }
override fun setDark(color: Int) { override fun setDark(color: Int) {
lastPlaybackControlsColor = Color.WHITE val colorBg = ATHUtil.resolveColor(activity, android.R.attr.colorBackground)
lastDisabledPlaybackControlsColor = ContextCompat.getColor(context!!, R.color.md_grey_500) 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) if (PreferenceUtil.getInstance().adaptiveColor) {
text.setTextColor(lastDisabledPlaybackControlsColor) setFabColor(color)
} else {
setProgressBarColor() setFabColor(ThemeStore.accentColor(context!!))
}
songCurrentProgress!!.setTextColor(lastPlaybackControlsColor)
songTotalTime!!.setTextColor(lastPlaybackControlsColor)
updateRepeatState() updateRepeatState()
updateShuffleState() updateShuffleState()
updatePrevNextColor() updatePrevNextColor()
} }
private fun setProgressBarColor() { private fun setFabColor(i: Int) {
TintHelper.setTintAuto(progressSlider!!, Color.WHITE, false) 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() { private fun setUpPlayPauseFab() {
TintHelper.setTintAuto(playPauseFab!!, Color.WHITE, true) playPauseButton.setOnClickListener(PlayPauseButtonOnClickHandler())
TintHelper.setTintAuto(playPauseFab!!, Color.BLACK, false)
playPauseFab!!.setOnClickListener(PlayPauseButtonOnClickHandler())
} }
protected fun updatePlayPauseDrawableState() { private fun updatePlayPauseDrawableState() {
if (MusicPlayerRemote.isPlaying) { if (MusicPlayerRemote.isPlaying) {
playPauseFab!!.setImageResource(R.drawable.ic_pause_white_24dp) playPauseButton.setImageResource(R.drawable.ic_pause_white_24dp)
} else { } else {
playPauseFab!!.setImageResource(R.drawable.ic_play_arrow_white_24dp) playPauseButton.setImageResource(R.drawable.ic_play_arrow_white_24dp)
} }
} }
private fun setUpMusicControllers() { private fun setUpMusicControllers() {
setUpPlayPauseFab() setUpPlayPauseFab()
setUpPrevNext() setUpPrevNext()
@ -147,50 +169,49 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
private fun setUpPrevNext() { private fun setUpPrevNext() {
updatePrevNextColor() updatePrevNextColor()
nextButton!!.setOnClickListener { MusicPlayerRemote.playNextSong() } nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
prevButton!!.setOnClickListener { MusicPlayerRemote.back() } previousButton.setOnClickListener { MusicPlayerRemote.back() }
} }
private fun updatePrevNextColor() { private fun updatePrevNextColor() {
nextButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) nextButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
prevButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) previousButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
private fun setUpShuffleButton() { private fun setUpShuffleButton() {
shuffleButton!!.setOnClickListener { MusicPlayerRemote.toggleShuffleMode() } shuffleButton.setOnClickListener { v -> MusicPlayerRemote.toggleShuffleMode() }
} }
override fun updateShuffleState() { override fun updateShuffleState() {
when (MusicPlayerRemote.shuffleMode) { when (MusicPlayerRemote.shuffleMode) {
MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) MusicService.SHUFFLE_MODE_SHUFFLE -> shuffleButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
else -> shuffleButton!!.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN) else -> shuffleButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
} }
private fun setUpRepeatButton() { private fun setUpRepeatButton() {
repeatButton!!.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() } repeatButton.setOnClickListener { MusicPlayerRemote.cycleRepeatMode() }
} }
override fun updateRepeatState() { override fun updateRepeatState() {
when (MusicPlayerRemote.repeatMode) { when (MusicPlayerRemote.repeatMode) {
MusicService.REPEAT_MODE_NONE -> { MusicService.REPEAT_MODE_NONE -> {
repeatButton!!.setImageResource(R.drawable.ic_repeat_white_24dp) repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
repeatButton!!.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN) repeatButton.setColorFilter(lastDisabledPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
MusicService.REPEAT_MODE_ALL -> { MusicService.REPEAT_MODE_ALL -> {
repeatButton!!.setImageResource(R.drawable.ic_repeat_white_24dp) repeatButton.setImageResource(R.drawable.ic_repeat_white_24dp)
repeatButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
MusicService.REPEAT_MODE_THIS -> { MusicService.REPEAT_MODE_THIS -> {
repeatButton!!.setImageResource(R.drawable.ic_repeat_one_white_24dp) repeatButton.setImageResource(R.drawable.ic_repeat_one_white_24dp)
repeatButton!!.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN) repeatButton.setColorFilter(lastPlaybackControlsColor, PorterDuff.Mode.SRC_IN)
} }
} }
} }
public override fun show() {
override fun show() { playPauseButton!!.animate()
playPauseFab!!.animate()
.scaleX(1f) .scaleX(1f)
.scaleY(1f) .scaleY(1f)
.rotation(360f) .rotation(360f)
@ -198,34 +219,61 @@ class BlurPlaybackControlsFragment : AbsPlayerControlsFragment() {
.start() .start()
} }
override fun hide() { public override fun hide() {
if (playPauseFab != null) { if (playPauseButton != null) {
playPauseFab!!.scaleX = 0f playPauseButton!!.apply {
playPauseFab!!.scaleY = 0f scaleX = 0f
playPauseFab!!.rotation = 0f scaleY = 0f
rotation = 0f
}
} }
} }
override fun setUpProgressSlider() { override fun setUpProgressSlider() {
progressSlider!!.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() { progressSlider.setOnSeekBarChangeListener(object : SimpleOnSeekbarChangeListener() {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
if (fromUser) { if (fromUser) {
MusicPlayerRemote.seekTo(progress) 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) { override fun onUpdateProgressViews(progress: Int, total: Int) {
progressSlider!!.max = total progressSlider.max = total
val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress) val animator = ObjectAnimator.ofInt(progressSlider, "progress", progress)
animator.duration = 1500 animator.duration = 1500
animator.interpolator = LinearInterpolator() animator.interpolator = LinearInterpolator()
animator.start() animator.start()
songTotalTime!!.text = MusicUtil.getReadableDurationString(total.toLong()) songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
songCurrentProgress!!.text = MusicUtil.getReadableDurationString(progress.toLong()) songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
} }
} }

View file

@ -6,10 +6,7 @@ import android.preference.PreferenceManager
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView import androidx.appcompat.widget.Toolbar
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.BlurTransformation 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.glide.SongGlideRequest
import code.name.monkey.retromusic.helper.MusicPlayerRemote import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song 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.base.AbsPlayerFragment
import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator import kotlinx.android.synthetic.main.fragment_blur.*
class BlurPlayerFragment : AbsPlayerFragment() { 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 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?, override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
@ -51,7 +47,7 @@ class BlurPlayerFragment : AbsPlayerFragment() {
} }
private fun setUpPlayerToolbar() { private fun setUpPlayerToolbar() {
toolbar!!.apply { playerToolbar!!.apply {
inflateMenu(R.menu.menu_player) inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { activity!!.onBackPressed() } setNavigationOnClickListener { activity!!.onBackPressed() }
ToolbarContentTintHelper.colorizeToolbar(this, Color.WHITE, activity) ToolbarContentTintHelper.colorizeToolbar(this, Color.WHITE, activity)
@ -66,7 +62,7 @@ class BlurPlayerFragment : AbsPlayerFragment() {
playbackControlsFragment.setDark(color) playbackControlsFragment.setDark(color)
lastColor = color lastColor = color
callbacks!!.onPaletteColorChanged() callbacks!!.onPaletteColorChanged()
ToolbarContentTintHelper.colorizeToolbar(toolbar!!, Color.WHITE, activity) ToolbarContentTintHelper.colorizeToolbar(playerToolbar!!, Color.WHITE, activity)
} }
override fun toggleFavorite(song: Song) { override fun toggleFavorite(song: Song) {
@ -95,15 +91,6 @@ class BlurPlayerFragment : AbsPlayerFragment() {
override val paletteColor: Int override val paletteColor: Int
get() = lastColor get() = lastColor
override fun onDestroyView() {
recyclerView!!.apply {
itemAnimator = null
adapter = null
}
playingQueueAdapter = null
layoutManager = null
super.onDestroyView()
}
private fun updateBlur() { private fun updateBlur() {
val activity = activity ?: return val activity = activity ?: return
@ -130,69 +117,11 @@ class BlurPlayerFragment : AbsPlayerFragment() {
override fun onServiceConnected() { override fun onServiceConnected() {
updateIsFavorite() updateIsFavorite()
updateBlur() updateBlur()
setUpRecyclerView()
} }
override fun onPlayingMetaChanged() { override fun onPlayingMetaChanged() {
updateIsFavorite() updateIsFavorite()
updateBlur() 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)
} }
} }

View file

@ -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()
}
}
}

View file

@ -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())
}
}

View file

@ -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()
}
}
}

View file

@ -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
}
}

View file

@ -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)
}
}
}

View file

@ -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()
}
}
}

View file

@ -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<IconImageView> 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<View> 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))));
}
}

View file

@ -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<ImageView>(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)
}
}
}

View file

@ -7,7 +7,7 @@ import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.preference.TwoStatePreference; import androidx.preference.TwoStatePreference;
import code.name.monkey.retromusic.R; 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; import code.name.monkey.retromusic.util.PreferenceUtil;
/** /**
@ -25,7 +25,7 @@ public class NowPlayingSettingsFragment extends AbsSettingsFragment implements
final TwoStatePreference carouselEffect = (TwoStatePreference) findPreference("carousel_effect"); final TwoStatePreference carouselEffect = (TwoStatePreference) findPreference("carousel_effect");
carouselEffect.setOnPreferenceChangeListener((preference, newValue) -> { 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)); showProToastAndNavigate(getActivity().getString(R.string.pref_title_toggle_carousel_effect));
return false; return false;
} }

View file

@ -7,7 +7,7 @@ import android.view.View;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.preference.TwoStatePreference; import androidx.preference.TwoStatePreference;
import code.name.monkey.retromusic.R; 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; import code.name.monkey.retromusic.util.PreferenceUtil;
public class PersonaizeSettingsFragment extends AbsSettingsFragment implements SharedPreferences.OnSharedPreferenceChangeListener { public class PersonaizeSettingsFragment extends AbsSettingsFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
@ -16,7 +16,7 @@ public class PersonaizeSettingsFragment extends AbsSettingsFragment implements S
public void invalidateSettings() { public void invalidateSettings() {
final TwoStatePreference cornerWindow = (TwoStatePreference) findPreference("corner_window"); final TwoStatePreference cornerWindow = (TwoStatePreference) findPreference("corner_window");
cornerWindow.setOnPreferenceChangeListener((preference, newValue) -> { 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)); showProToastAndNavigate(getActivity().getString(R.string.pref_title_round_corners));
return false; return false;
} }

View file

@ -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.ColorUtil;
import code.name.monkey.appthemehelper.util.VersionUtils; import code.name.monkey.appthemehelper.util.VersionUtils;
import code.name.monkey.retromusic.R; 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.ui.activities.SettingsActivity;
import code.name.monkey.retromusic.util.PreferenceUtil; import code.name.monkey.retromusic.util.PreferenceUtil;
@ -48,7 +48,7 @@ public class ThemeSettingsFragment extends AbsSettingsFragment {
generalTheme.setOnPreferenceChangeListener((preference, newValue) -> { generalTheme.setOnPreferenceChangeListener((preference, newValue) -> {
String theme = (String) newValue; String theme = (String) newValue;
if (theme.equals("color") && !RetroApplication.Companion.isProVersion()) { if (theme.equals("color") && !App.Companion.isProVersion()) {
primaryColorPref.setVisible(false); primaryColorPref.setVisible(false);
showProToastAndNavigate("Color theme"); showProToastAndNavigate("Color theme");
return false; return false;

View file

@ -22,7 +22,7 @@ import java.io.OutputStream;
import java.util.Locale; import java.util.Locale;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import code.name.monkey.retromusic.RetroApplication; import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.model.Artist; import code.name.monkey.retromusic.model.Artist;
@ -55,12 +55,12 @@ public class CustomArtistImageUtil {
} }
public static File getFile(Artist artist) { 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)); return new File(dir, getFileName(artist));
} }
public void setCustomArtistImage(final Artist artist, Uri uri) { public void setCustomArtistImage(final Artist artist, Uri uri) {
Glide.with(RetroApplication.Companion.getInstance()) Glide.with(App.Companion.getInstance())
.load(uri) .load(uri)
.asBitmap() .asBitmap()
.diskCacheStrategy(DiskCacheStrategy.NONE) .diskCacheStrategy(DiskCacheStrategy.NONE)
@ -70,7 +70,7 @@ public class CustomArtistImageUtil {
public void onLoadFailed(Exception e, Drawable errorDrawable) { public void onLoadFailed(Exception e, Drawable errorDrawable) {
super.onLoadFailed(e, errorDrawable); super.onLoadFailed(e, errorDrawable);
e.printStackTrace(); 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") @SuppressLint("StaticFieldLeak")
@ -80,7 +80,7 @@ public class CustomArtistImageUtil {
@SuppressLint("ApplySharedPref") @SuppressLint("ApplySharedPref")
@Override @Override
protected Void doInBackground(Void... params) { 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.exists()) {
if (!dir.mkdirs()) { // create the folder if (!dir.mkdirs()) { // create the folder
return null; return null;
@ -94,13 +94,13 @@ public class CustomArtistImageUtil {
succesful = ImageUtil.resizeBitmap(resource, 2048).compress(Bitmap.CompressFormat.JPEG, 100, os); succesful = ImageUtil.resizeBitmap(resource, 2048).compress(Bitmap.CompressFormat.JPEG, 100, os);
os.close(); os.close();
} catch (IOException e) { } 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) { if (succesful) {
mPreferences.edit().putBoolean(getFileName(artist), true).commit(); mPreferences.edit().putBoolean(getFileName(artist), true).commit();
ArtistSignatureUtil.getInstance(RetroApplication.Companion.getInstance()).updateArtistSignature(artist.getName()); ArtistSignatureUtil.getInstance(App.Companion.getInstance()).updateArtistSignature(artist.getName());
RetroApplication.Companion.getInstance().getContentResolver().notifyChange(Uri.parse("content://media"), null); // trigger media store changed to force artist image reload App.Companion.getInstance().getContentResolver().notifyChange(Uri.parse("content://media"), null); // trigger media store changed to force artist image reload
} }
return null; return null;
} }
@ -116,8 +116,8 @@ public class CustomArtistImageUtil {
@Override @Override
protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) {
mPreferences.edit().putBoolean(getFileName(artist), false).commit(); mPreferences.edit().putBoolean(getFileName(artist), false).commit();
ArtistSignatureUtil.getInstance(RetroApplication.Companion.getInstance()).updateArtistSignature(artist.getName()); ArtistSignatureUtil.getInstance(App.Companion.getInstance()).updateArtistSignature(artist.getName());
RetroApplication.Companion.getInstance().getContentResolver().notifyChange(Uri.parse("content://media"), null); // trigger media store changed to force artist image reload App.Companion.getInstance().getContentResolver().notifyChange(Uri.parse("content://media"), null); // trigger media store changed to force artist image reload
File file = getFile(artist); File file = getFile(artist);
if (!file.exists()) { if (!file.exists()) {

View file

@ -34,7 +34,6 @@ import code.name.monkey.retromusic.ui.activities.UserInfoActivity;
import code.name.monkey.retromusic.ui.activities.WhatsNewActivity; 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.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; 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) { public static void goToPlaylistNew(@NonNull Activity activity, Playlist playlist) {
Intent intent = new Intent(activity, PlaylistDetailActivity.class); 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); ActivityCompat.startActivity(activity, intent, null);
} }
@ -102,7 +101,7 @@ public class NavigationUtil {
public static void goToGenre(@NonNull Activity activity, @NonNull Genre genre) { public static void goToGenre(@NonNull Activity activity, @NonNull Genre genre) {
Intent intent = new Intent(activity, GenreDetailsActivity.class); 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); ActivityCompat.startActivity(activity, intent, null);
} }

View file

@ -21,8 +21,8 @@ import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.StyleRes; import androidx.annotation.StyleRes;
import androidx.viewpager.widget.ViewPager; import androidx.viewpager.widget.ViewPager;
import code.name.monkey.retromusic.App;
import code.name.monkey.retromusic.R; import code.name.monkey.retromusic.R;
import code.name.monkey.retromusic.RetroApplication;
import code.name.monkey.retromusic.helper.SortOrder; import code.name.monkey.retromusic.helper.SortOrder;
import code.name.monkey.retromusic.model.CategoryInfo; import code.name.monkey.retromusic.model.CategoryInfo;
import code.name.monkey.retromusic.transform.CascadingPageTransformer; import code.name.monkey.retromusic.transform.CascadingPageTransformer;
@ -122,7 +122,7 @@ public final class PreferenceUtil {
public static PreferenceUtil getInstance() { public static PreferenceUtil getInstance() {
if (sInstance == null) { if (sInstance == null) {
sInstance = new PreferenceUtil(RetroApplication.Companion.getContext()); sInstance = new PreferenceUtil(App.Companion.getContext());
} }
return sInstance; return sInstance;
} }
@ -279,7 +279,7 @@ public final class PreferenceUtil {
public final int getLastPage() { 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) { public void setLastPage(final int value) {

View file

@ -46,7 +46,7 @@ import androidx.core.content.ContextCompat;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat; import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import code.name.monkey.appthemehelper.ThemeStore; import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.appthemehelper.util.TintHelper; import code.name.monkey.appthemehelper.util.TintHelper;
import code.name.monkey.retromusic.RetroApplication; import code.name.monkey.retromusic.App;
public class RetroUtil { public class RetroUtil {
@ -84,11 +84,11 @@ public class RetroUtil {
} }
public static boolean isTablet() { public static boolean isTablet() {
return RetroApplication.Companion.getContext().getResources().getConfiguration().smallestScreenWidthDp >= 600; return App.Companion.getContext().getResources().getConfiguration().smallestScreenWidthDp >= 600;
} }
public static boolean isLandscape() { 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) @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@ -199,8 +199,8 @@ public class RetroUtil {
public static Drawable getTintedDrawable(@DrawableRes int id) { public static Drawable getTintedDrawable(@DrawableRes int id) {
return TintHelper return TintHelper
.createTintedDrawable(ContextCompat.getDrawable(RetroApplication.Companion.getInstance(), id), .createTintedDrawable(ContextCompat.getDrawable(App.Companion.getInstance(), id),
ThemeStore.accentColor(RetroApplication.Companion.getInstance())); ThemeStore.accentColor(App.Companion.getInstance()));
} }
public static Bitmap createBitmap(Drawable drawable, float sizeMultiplier) { public static Bitmap createBitmap(Drawable drawable, float sizeMultiplier) {
@ -297,9 +297,9 @@ public class RetroUtil {
public static int getStatusBarHeight() { public static int getStatusBarHeight() {
int result = 0; 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) { if (resourceId > 0) {
result = RetroApplication.Companion.getContext().getResources().getDimensionPixelSize(resourceId); result = App.Companion.getContext().getResources().getDimensionPixelSize(resourceId);
} }
return result; return result;
} }
@ -337,9 +337,9 @@ public class RetroUtil {
public static int getNavigationBarHeight(Activity activity) { public static int getNavigationBarHeight(Activity activity) {
/* int result = 0; /* 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) { if (resourceId > 0) {
result = RetroApplication.getContext().getResources().getDimensionPixelSize(resourceId); result = App.getContext().getResources().getDimensionPixelSize(resourceId);
} }
return result;*/ return result;*/
DisplayMetrics metrics = new DisplayMetrics(); DisplayMetrics metrics = new DisplayMetrics();
@ -415,7 +415,7 @@ public class RetroUtil {
} }
public static boolean checkNavigationBarHeight() { public static boolean checkNavigationBarHeight() {
Resources resources = RetroApplication.Companion.getContext().getResources(); Resources resources = App.Companion.getContext().getResources();
int orientation = resources.getConfiguration().orientation; int orientation = resources.getConfiguration().orientation;
if (!hasNavBar(resources)) { if (!hasNavBar(resources)) {
return false; return false;

View file

@ -7,7 +7,7 @@ import android.content.res.Resources;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.view.ViewGroup; import android.view.ViewGroup;
import code.name.monkey.retromusic.RetroApplication; import code.name.monkey.retromusic.App;
public class SystemUtils { public class SystemUtils {
@ -38,9 +38,9 @@ public class SystemUtils {
public static int getNavigationBarHeight() { public static int getNavigationBarHeight() {
int result = 0; 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) { if (resourceId > 0) {
result = RetroApplication.Companion.getContext().getResources().getDimensionPixelSize(resourceId); result = App.Companion.getContext().getResources().getDimensionPixelSize(resourceId);
} }
return result; return result;
} }

View file

@ -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()))));
}
}

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/navigation_view_item" android:state_checked="true" />
<item android:drawable="@android:color/transparent" />
</selector>

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/md_red_400" />
<corners
android:bottomRightRadius="25dp"
android:topRightRadius="25dp" />
</shape>

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android"> <font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font <font
android:font="@font/circular_std_book" android:font="@font/sans_regular"
android:fontStyle="normal" android:fontStyle="normal"
android:fontWeight="400" /> android:fontWeight="400" />
<font <font
android:font="@font/circular_std_black" android:font="@font/sans_bold"
android:fontStyle="normal" android:fontStyle="normal"
android:fontWeight="700" /> android:fontWeight="700" />
</font-family> </font-family>

Binary file not shown.

Binary file not shown.

View file

@ -8,7 +8,7 @@
android:focusable="true"> android:focusable="true">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/gradient_background" android:id="@+id/colorBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:scaleType="centerCrop" /> android:scaleType="centerCrop" />
@ -31,16 +31,20 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical"> android:orientation="vertical">
<include layout="@layout/status_bar" /> <FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="@layout/status_bar" />
</FrameLayout>
<FrameLayout <FrameLayout
android:id="@+id/toolbar_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0"> android:layout_weight="0">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/player_toolbar" android:id="@+id/playerToolbar"
style="@style/Toolbar" style="@style/Toolbar"
android:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp" android:navigationIcon="@drawable/ic_keyboard_arrow_down_black_24dp"
app:contentInsetLeft="0dp" app:contentInsetLeft="0dp"
@ -54,7 +58,7 @@
</FrameLayout> </FrameLayout>
<FrameLayout <FrameLayout
android:id="@+id/album_cover_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginStart="64dp" android:layout_marginStart="64dp"
@ -62,7 +66,7 @@
android:layout_weight="1"> android:layout_weight="1">
<fragment <fragment
android:id="@+id/player_album_cover_fragment" android:id="@+id/playerAlbumCoverFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
@ -78,7 +82,7 @@
android:layout_marginEnd="96dp"> android:layout_marginEnd="96dp">
<fragment <fragment
android:id="@+id/playback_controls_fragment" android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.cardblur.CardBlurPlaybackControlsFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.cardblur.CardBlurPlaybackControlsFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View file

@ -8,13 +8,8 @@
android:clickable="true" android:clickable="true"
android:focusable="true"> android:focusable="true">
<View
android:id="@+id/gradient_background"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<fragment <fragment
android:id="@+id/player_album_cover_fragment" android:id="@+id/playerAlbumCoverFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
@ -38,13 +33,13 @@
</FrameLayout> </FrameLayout>
<FrameLayout <FrameLayout
android:id="@+id/toolbar_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0"> android:layout_weight="0">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/player_toolbar" android:id="@+id/playerToolbar"
style="@style/Toolbar" style="@style/Toolbar"
android:navigationIcon="@drawable/ic_close_white_24dp" android:navigationIcon="@drawable/ic_close_white_24dp"
app:navigationIcon="@drawable/ic_close_white_24dp" /> app:navigationIcon="@drawable/ic_close_white_24dp" />
@ -71,7 +66,7 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<fragment <fragment
android:id="@+id/playback_controls_fragment" android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.card.CardPlaybackControlsFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.card.CardPlaybackControlsFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View file

@ -9,7 +9,7 @@
android:orientation="vertical"> android:orientation="vertical">
<View <View
android:id="@+id/gradient_background" android:id="@+id/colorGradientBackground"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" />
@ -42,7 +42,7 @@
android:layout_height="match_parent"> android:layout_height="match_parent">
<fragment <fragment
android:id="@+id/player_album_cover_fragment" android:id="@+id/playerAlbumCoverFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -56,21 +56,19 @@
android:orientation="vertical"> android:orientation="vertical">
<FrameLayout <FrameLayout
android:id="@+id/toolbar_container"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="0"> android:layout_weight="0">
<androidx.appcompat.widget.Toolbar <androidx.appcompat.widget.Toolbar
android:id="@+id/player_toolbar" android:id="@+id/playerToolbar"
style="@style/Toolbar48" style="@style/Toolbar"
android:layout_height="48dp"
android:navigationIcon="@drawable/ic_close_white_24dp" android:navigationIcon="@drawable/ic_close_white_24dp"
app:navigationIcon="@drawable/ic_close_white_24dp" /> app:navigationIcon="@drawable/ic_close_white_24dp" />
</FrameLayout> </FrameLayout>
<fragment <fragment
android:id="@+id/playback_controls_fragment" android:id="@+id/playbackControlsFragment"
android:name="code.name.monkey.retromusic.ui.fragments.player.flat.FlatPlaybackControlsFragment" android:name="code.name.monkey.retromusic.ui.fragments.player.flat.FlatPlaybackControlsFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"

View file

@ -25,24 +25,19 @@
android:elevation="0dp" android:elevation="0dp"
app:elevation="0dp"> app:elevation="0dp">
<FrameLayout <androidx.appcompat.widget.Toolbar
android:layout_width="match_parent" android:id="@+id/toolbar"
android:layout_height="wrap_content" style="@style/Toolbar"
android:layout_gravity="center_vertical"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
tools:ignore="UnusedAttribute"> tools:ignore="UnusedAttribute">
<androidx.appcompat.widget.AppCompatImageView <code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView
android:id="@+id/searchIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
app:srcCompat="@drawable/ic_search_white_24dp"
app:tint="@color/md_white_1000" />
<TextView
android:id="@+id/bannerTitle" android:id="@+id/bannerTitle"
style="@style/BigTitleTextAppearanceToolbar" style="@style/BigTitleTextAppearanceToolbar"
android:text="@string/app_name" android:text="@string/app_name"
android:textColor="@color/md_white_1000" /> tools:ignore="MissingPrefix" />
<code.name.monkey.retromusic.views.CircularImageView <code.name.monkey.retromusic.views.CircularImageView
android:id="@+id/userImage" android:id="@+id/userImage"
@ -51,7 +46,7 @@
android:layout_gravity="end|center_vertical" android:layout_gravity="end|center_vertical"
android:layout_marginEnd="16dp" android:layout_marginEnd="16dp"
app:civ_border="false" /> app:civ_border="false" />
</FrameLayout> </androidx.appcompat.widget.Toolbar>
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView

Some files were not shown because too many files have changed in this diff Show more