Fix Preference list selection and Favourite Song
This commit is contained in:
parent
263620310f
commit
9156ec2390
33 changed files with 192 additions and 237 deletions
app
build.gradle
gradle.propertiessrc/main
java/code/name/monkey/retromusic
dialogs
helper
loaders
model
preferences
ui/fragments
base
player
adaptive
blur
card
cardblur
classic
color
fit
flat
full
material
normal
plain
simple
tiny
util
views
res
|
@ -32,7 +32,7 @@ android {
|
|||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
applicationId "code.name.monkey.retromusic"
|
||||
versionCode 299
|
||||
versionCode 230
|
||||
versionName '3.1.250'
|
||||
|
||||
multiDexEnabled true
|
||||
|
|
|
@ -49,9 +49,8 @@ class OptionsSheetDialogFragment : RoundedBottomSheetDialogFragment(), View.OnCl
|
|||
get() {
|
||||
var message = getString(R.string.title_good_day)
|
||||
val c = Calendar.getInstance()
|
||||
val timeOfDay = c.get(Calendar.HOUR_OF_DAY)
|
||||
|
||||
when (timeOfDay) {
|
||||
when (c.get(Calendar.HOUR_OF_DAY)) {
|
||||
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)
|
||||
|
|
|
@ -21,6 +21,7 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.model.PlaylistSong
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
|
@ -61,6 +62,7 @@ class RemoveFromPlaylistDialog : RoundedBottomSheetDialogFragment() {
|
|||
PlaylistsUtil.removeFromPlaylist(activity!!, playlistSongs)
|
||||
dismiss()
|
||||
}
|
||||
MaterialUtil.setTint(this)
|
||||
}
|
||||
bannerTitle.apply {
|
||||
setText(title)
|
||||
|
@ -70,6 +72,7 @@ class RemoveFromPlaylistDialog : RoundedBottomSheetDialogFragment() {
|
|||
actionCancel.apply {
|
||||
setTextColor(ThemeStore.textColorSecondary(context))
|
||||
setOnClickListener { dismiss() }
|
||||
MaterialUtil.setTint(this, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
package code.name.monkey.retromusic.helper;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader;
|
||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist;
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import io.reactivex.Observable;
|
||||
|
||||
public class M3UWriter implements M3UConstants {
|
||||
|
||||
public static Observable<File> write(Context context, File dir, Playlist playlist) throws IOException {
|
||||
if (!dir.exists()) //noinspection ResultOfMethodCallIgnored
|
||||
dir.mkdirs();
|
||||
File file = new File(dir, playlist.name.concat("." + M3UConstants.Companion.getEXTENSION()));
|
||||
|
||||
ArrayList<? extends Song> songs;
|
||||
if (playlist instanceof AbsCustomPlaylist) {
|
||||
songs = ((AbsCustomPlaylist) playlist).getSongs(context).blockingFirst();
|
||||
} else {
|
||||
songs = PlaylistSongsLoader.INSTANCE.getPlaylistSongList(context, playlist.id).blockingFirst();
|
||||
}
|
||||
|
||||
|
||||
if (songs.size() > 0) {
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
|
||||
|
||||
bw.write(M3UConstants.Companion.getHEADER());
|
||||
for (Song song : songs) {
|
||||
bw.newLine();
|
||||
bw.write(M3UConstants.Companion.getENTRY() + song.getDuration() + M3UConstants.Companion.getDURATION_SEPARATOR() + song.getArtistName() + " - " + song.getTitle());
|
||||
bw.newLine();
|
||||
bw.write(song.getData());
|
||||
}
|
||||
|
||||
bw.close();
|
||||
}
|
||||
|
||||
return Observable.just(file);
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
package code.name.monkey.retromusic.helper
|
||||
|
||||
import android.content.Context
|
||||
import code.name.monkey.retromusic.loaders.PlaylistSongsLoader
|
||||
import code.name.monkey.retromusic.model.AbsCustomPlaylist
|
||||
import code.name.monkey.retromusic.model.Playlist
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.ObservableEmitter
|
||||
import java.io.BufferedWriter
|
||||
import java.io.File
|
||||
import java.io.FileWriter
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
|
||||
class M3UWriter : M3UConstants {
|
||||
companion object {
|
||||
val TAG: String = M3UWriter::class.java.simpleName
|
||||
|
||||
fun write(context: Context,
|
||||
dir: File, playlist: Playlist): Observable<File> {
|
||||
if (!dir.exists())
|
||||
|
||||
dir.mkdirs()
|
||||
val file = File(dir, playlist.name + ("." + M3UConstants.EXTENSION))
|
||||
|
||||
return if (playlist is AbsCustomPlaylist) {
|
||||
Observable.create { e -> playlist.getSongs(context).subscribe { songs -> saveSongsToFile(file, e, songs) } }
|
||||
} else
|
||||
Observable.create { e -> PlaylistSongsLoader.getPlaylistSongList(context, playlist.id).subscribe { songs -> saveSongsToFile(file, e, songs) } }
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
private fun saveSongsToFile(file: File, e: ObservableEmitter<File>, songs: ArrayList<Song>) {
|
||||
if (songs.size > 0) {
|
||||
val bw = BufferedWriter(FileWriter(file))
|
||||
bw.write(M3UConstants.HEADER)
|
||||
for (song in songs) {
|
||||
bw.newLine()
|
||||
bw.write(M3UConstants.ENTRY + song.duration + M3UConstants.DURATION_SEPARATOR + song.artistName + " - " + song.title)
|
||||
bw.newLine()
|
||||
bw.write(song.data)
|
||||
}
|
||||
|
||||
bw.close()
|
||||
}
|
||||
e.onNext(file)
|
||||
e.onComplete()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,21 +29,21 @@ import java.util.*
|
|||
*/
|
||||
|
||||
object PlaylistLoader {
|
||||
fun makePlaylistCursor(context: Context, selection: String?, values: Array<String>?): Cursor? {
|
||||
try {
|
||||
return context.contentResolver.query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
|
||||
private fun makePlaylistCursor(context: Context, selection: String?, values: Array<String>?): Cursor? {
|
||||
return try {
|
||||
context.contentResolver.query(MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
|
||||
arrayOf(
|
||||
/* 0 */
|
||||
BaseColumns._ID,
|
||||
/* 1 */
|
||||
PlaylistsColumns.NAME), selection, values, MediaStore.Audio.Playlists.DEFAULT_SORT_ORDER)
|
||||
} catch (e: SecurityException) {
|
||||
return null
|
||||
}
|
||||
|
||||
} catch (e: SecurityException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
fun getPlaylist(cursor: Cursor?): Observable<Playlist> {
|
||||
private fun getPlaylist(cursor: Cursor?): Observable<Playlist> {
|
||||
return Observable.create { e ->
|
||||
var playlist = Playlist()
|
||||
|
||||
|
@ -83,7 +83,7 @@ object PlaylistLoader {
|
|||
}
|
||||
|
||||
|
||||
fun getAllPlaylists(cursor: Cursor?): Observable<ArrayList<Playlist>> {
|
||||
private fun getAllPlaylists(cursor: Cursor?): Observable<ArrayList<Playlist>> {
|
||||
return Observable.create { e ->
|
||||
val playlists = ArrayList<Playlist>()
|
||||
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 Hemanth Savarala.
|
||||
*
|
||||
* Licensed under the GNU General Public License v3
|
||||
*
|
||||
* This is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
package code.name.monkey.retromusic.model;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
|
||||
public class CategoryInfo implements Parcelable {
|
||||
public static final Parcelable.Creator<CategoryInfo> CREATOR = new Parcelable.Creator<CategoryInfo>() {
|
||||
public CategoryInfo createFromParcel(Parcel source) {
|
||||
return new CategoryInfo(source);
|
||||
}
|
||||
|
||||
public CategoryInfo[] newArray(int size) {
|
||||
return new CategoryInfo[size];
|
||||
}
|
||||
};
|
||||
public Category category;
|
||||
public boolean visible;
|
||||
|
||||
public CategoryInfo(Category category, boolean visible) {
|
||||
this.category = category;
|
||||
this.visible = visible;
|
||||
}
|
||||
|
||||
|
||||
private CategoryInfo(Parcel source) {
|
||||
category = (Category) source.readSerializable();
|
||||
visible = source.readInt() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeSerializable(category);
|
||||
dest.writeInt(visible ? 1 : 0);
|
||||
}
|
||||
|
||||
public enum Category {
|
||||
SONGS(R.string.songs),
|
||||
ALBUMS(R.string.albums),
|
||||
ARTISTS(R.string.artists),
|
||||
GENRES(R.string.genres),
|
||||
PLAYLISTS(R.string.playlists);
|
||||
|
||||
public final int stringRes;
|
||||
|
||||
Category(int stringRes) {
|
||||
this.stringRes = stringRes;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -66,7 +66,7 @@ class MaterialListPreferenceDialog : PreferenceDialogFragmentCompat() {
|
|||
return MaterialDialog(activity!!).show {
|
||||
title(text = materialListPreference.title.toString())
|
||||
positiveButton(R.string.set)
|
||||
listItemsSingleChoice(items = entries, initialSelection = position) { _, index, _ ->
|
||||
listItemsSingleChoice(items = entries, initialSelection = position, waitForPositiveButton = true) { _, index, _ ->
|
||||
materialListPreference.callChangeListener(entriesValues!![index])
|
||||
materialListPreference.setCustomValue(entriesValues[index])
|
||||
materialListPreference.summary = entries!![index]
|
||||
|
|
|
@ -146,7 +146,7 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem
|
|||
MusicUtil.toggleFavorite(activity!!, song)
|
||||
}
|
||||
|
||||
abstract fun toolbarGet(): Toolbar
|
||||
abstract fun playerToolbar(): Toolbar
|
||||
|
||||
abstract fun onShow()
|
||||
|
||||
|
@ -179,11 +179,11 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem
|
|||
updateIsFavoriteTask = object : AsyncTask<Song, Void, Boolean>() {
|
||||
override fun doInBackground(vararg params: Song): Boolean? {
|
||||
val activity = activity
|
||||
if (activity != null) {
|
||||
return MusicUtil.isFavorite(getActivity()!!, params[0])
|
||||
return if (activity != null) {
|
||||
MusicUtil.isFavorite(activity, params[0])
|
||||
} else {
|
||||
cancel(false)
|
||||
return null
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,11 +191,12 @@ abstract class AbsPlayerFragment : AbsMusicServiceFragment(), Toolbar.OnMenuItem
|
|||
val activity = activity
|
||||
if (activity != null) {
|
||||
val res = if (isFavorite!!)
|
||||
code.name.monkey.retromusic.R.drawable.ic_favorite_white_24dp
|
||||
R.drawable.ic_favorite_white_24dp
|
||||
else
|
||||
code.name.monkey.retromusic.R.drawable.ic_favorite_border_white_24dp
|
||||
R.drawable.ic_favorite_border_white_24dp
|
||||
val drawable = RetroUtil.getTintedVectorDrawable(activity, res, toolbarIconColor())
|
||||
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)
|
||||
if (playerToolbar().menu.findItem(R.id.action_toggle_favorite) != null)
|
||||
playerToolbar().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)
|
||||
|
|
|
@ -16,7 +16,7 @@ import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
|
|||
import kotlinx.android.synthetic.main.fragment_adaptive_player.*
|
||||
|
||||
class AdaptiveFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
|
|||
import kotlinx.android.synthetic.main.fragment_blur.*
|
||||
|
||||
class BlurPlayerFragment : AbsPlayerFragment() {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment
|
|||
import kotlinx.android.synthetic.main.fragment_card_player.*
|
||||
|
||||
class CardFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import code.name.monkey.retromusic.ui.fragments.player.normal.PlayerFragment
|
|||
import kotlinx.android.synthetic.main.fragment_card_blur_player.*
|
||||
|
||||
class CardBlurFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Call
|
|||
}
|
||||
}
|
||||
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ import com.bumptech.glide.request.transition.Transition
|
|||
import kotlinx.android.synthetic.main.fragment_color_player.*
|
||||
|
||||
class ColorFragment : AbsPlayerFragment() {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import kotlinx.android.synthetic.main.fragment_fit.*
|
|||
|
||||
|
||||
class FitFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ import code.name.monkey.retromusic.views.DrawableGradient
|
|||
import kotlinx.android.synthetic.main.fragment_flat_player.*
|
||||
|
||||
class FlatPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -55,16 +55,18 @@ class FullPlaybackControlsFragment : AbsPlayerControlsFragment(), PopupMenu.OnMe
|
|||
return inflater.inflate(R.layout.fragment_full_player_controls, container, false)
|
||||
}
|
||||
|
||||
private lateinit var volumeFragment: VolumeFragment
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setUpMusicControllers()
|
||||
|
||||
val volumeFragment = childFragmentManager.findFragmentById(R.id.volumeFragment) as VolumeFragment?
|
||||
volumeFragment!!.tintWhiteColor()
|
||||
|
||||
volumeFragment = childFragmentManager.findFragmentById(R.id.volumeFragment) as VolumeFragment
|
||||
|
||||
songTotalTime.setTextColor(Color.WHITE)
|
||||
songCurrentProgress.setTextColor(Color.WHITE)
|
||||
|
||||
title.isSelected = true
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -115,6 +117,7 @@ class FullPlaybackControlsFragment : AbsPlayerControlsFragment(), PopupMenu.OnMe
|
|||
} else {
|
||||
ThemeStore.accentColor(context!!)
|
||||
}
|
||||
volumeFragment.setTintableColor(colorFinal)
|
||||
text.setTextColor(colorFinal)
|
||||
|
||||
ViewUtil.setProgressDrawable(progressSlider, colorFinal, true)
|
||||
|
|
|
@ -25,7 +25,7 @@ import io.reactivex.schedulers.Schedulers
|
|||
import kotlinx.android.synthetic.main.fragment_full.*
|
||||
|
||||
class FullPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,8 @@ class FullPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbac
|
|||
setUpSubFragments()
|
||||
setUpPlayerToolbar()
|
||||
setupArtist()
|
||||
|
||||
nextSong.isSelected = true
|
||||
}
|
||||
|
||||
private fun setupArtist() {
|
||||
|
|
|
@ -19,7 +19,7 @@ import kotlinx.android.synthetic.main.fragment_material.*
|
|||
* @author Hemanth S (h4h13).
|
||||
*/
|
||||
class MaterialFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
|||
}
|
||||
|
||||
private fun setUpPlayerToolbar() {
|
||||
playerToolbar.inflateMenu(code.name.monkey.retromusic.R.menu.menu_player)
|
||||
playerToolbar.inflateMenu(R.menu.menu_player)
|
||||
playerToolbar.setNavigationOnClickListener { activity!!.onBackPressed() }
|
||||
playerToolbar.setOnMenuItemClickListener(this)
|
||||
|
||||
|
@ -138,7 +138,7 @@ class PlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
|||
updateIsFavorite()
|
||||
}
|
||||
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import code.name.monkey.retromusic.ui.fragments.player.PlayerAlbumCoverFragment
|
|||
import kotlinx.android.synthetic.main.fragment_plain_player.*
|
||||
|
||||
class PlainPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import kotlinx.android.synthetic.main.fragment_simple_player.*
|
|||
*/
|
||||
|
||||
class SimplePlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Callbacks {
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class TinyPlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Ca
|
|||
}
|
||||
|
||||
|
||||
override fun toolbarGet(): Toolbar {
|
||||
override fun playerToolbar(): Toolbar {
|
||||
return playerToolbar
|
||||
}
|
||||
|
||||
|
|
|
@ -388,14 +388,6 @@ public class MusicUtil {
|
|||
}
|
||||
|
||||
public static boolean isFavorite(@NonNull final Context context, @NonNull final Song song) {
|
||||
/*return Observable.create(e -> getFavoritesPlaylist(context).subscribe(playlist1 -> {
|
||||
boolean isBoolean = PlaylistsUtil.doPlaylistContains(context, playlist1.id, song.id);
|
||||
e.onNext(isBoolean);
|
||||
e.onComplete();
|
||||
}));*/
|
||||
|
||||
//getFavoritesPlaylist(context).blockingFirst().id.subscribe(MusicUtil::setPlaylist);
|
||||
//return PlaylistsUtil.doPlaylistContains(context, getFavoritesPlaylist(context).blockingFirst().id, song.id);
|
||||
return PlaylistsUtil
|
||||
.doPlaylistContains(context, getFavoritesPlaylist(context).blockingFirst().id, song.getId());
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
package code.name.monkey.retromusic.util;
|
||||
|
||||
|
||||
import android.content.ContentResolver;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
|
@ -25,37 +26,33 @@ import android.provider.MediaStore;
|
|||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import code.name.monkey.retromusic.R;
|
||||
import code.name.monkey.retromusic.helper.M3UWriter;
|
||||
import code.name.monkey.retromusic.model.Playlist;
|
||||
import code.name.monkey.retromusic.model.PlaylistSong;
|
||||
import code.name.monkey.retromusic.model.Song;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.annotations.NonNull;
|
||||
import io.reactivex.annotations.Nullable;
|
||||
|
||||
import static android.provider.MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
|
||||
|
||||
|
||||
public class PlaylistsUtil {
|
||||
public static boolean doesPlaylistExist(@NonNull final Context context, final int playlistId) {
|
||||
if (playlistId == -1) {
|
||||
return false;
|
||||
}
|
||||
return playlistId != -1 && doesPlaylistExist(context,
|
||||
MediaStore.Audio.Playlists._ID + "=?",
|
||||
new String[]{String.valueOf(playlistId)});
|
||||
}
|
||||
|
||||
Cursor cursor = context.getContentResolver().query(
|
||||
MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId),
|
||||
new String[]{}, null, null, null);
|
||||
|
||||
if (cursor == null || cursor.getCount() == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
cursor.close();
|
||||
return true;
|
||||
public static boolean doesPlaylistExist(@NonNull final Context context, final String name) {
|
||||
return doesPlaylistExist(context,
|
||||
MediaStore.Audio.PlaylistsColumns.NAME + "=?",
|
||||
new String[]{name});
|
||||
}
|
||||
|
||||
public static int createPlaylist(@NonNull final Context context, @Nullable final String name) {
|
||||
|
@ -63,7 +60,9 @@ public class PlaylistsUtil {
|
|||
if (name != null && name.length() > 0) {
|
||||
try {
|
||||
Cursor cursor = context.getContentResolver().query(EXTERNAL_CONTENT_URI,
|
||||
new String[]{MediaStore.Audio.Playlists._ID}, MediaStore.Audio.PlaylistsColumns.NAME + "=?", new String[]{name}, null);
|
||||
new String[]{MediaStore.Audio.Playlists._ID},
|
||||
MediaStore.Audio.PlaylistsColumns.NAME + "=?", new String[]{name},
|
||||
null);
|
||||
if (cursor == null || cursor.getCount() < 1) {
|
||||
final ContentValues values = new ContentValues(1);
|
||||
values.put(MediaStore.Audio.PlaylistsColumns.NAME, name);
|
||||
|
@ -71,13 +70,14 @@ public class PlaylistsUtil {
|
|||
EXTERNAL_CONTENT_URI,
|
||||
values);
|
||||
if (uri != null) {
|
||||
// necessary because somehow the MediaStoreObserver is not notified when adding a playlist
|
||||
// Necessary because somehow the MediaStoreObserver is not notified when adding a playlist
|
||||
context.getContentResolver().notifyChange(Uri.parse("content://media"), null);
|
||||
Toast.makeText(context, context.getResources().getString(
|
||||
R.string.created_playlist_x, name), Toast.LENGTH_SHORT).show();
|
||||
id = Integer.parseInt(uri.getLastPathSegment());
|
||||
}
|
||||
} else {
|
||||
// Playlist exists
|
||||
if (cursor.moveToFirst()) {
|
||||
id = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Playlists._ID));
|
||||
}
|
||||
|
@ -107,6 +107,7 @@ public class PlaylistsUtil {
|
|||
selection.append(")");
|
||||
try {
|
||||
context.getContentResolver().delete(EXTERNAL_CONTENT_URI, selection.toString(), null);
|
||||
context.getContentResolver().notifyChange(Uri.parse("content://media"), null);
|
||||
} catch (SecurityException ignored) {
|
||||
}
|
||||
}
|
||||
|
@ -120,7 +121,9 @@ public class PlaylistsUtil {
|
|||
public static void addToPlaylist(@NonNull final Context context, @NonNull final List<Song> songs, final int playlistId, final boolean showToastOnFinish) {
|
||||
final int size = songs.size();
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
final String[] projection = new String[]{"max(" + MediaStore.Audio.Playlists.Members.PLAY_ORDER + ")",};
|
||||
final String[] projection = new String[]{
|
||||
"max(" + MediaStore.Audio.Playlists.Members.PLAY_ORDER + ")",
|
||||
};
|
||||
final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
|
||||
Cursor cursor = null;
|
||||
int base = 0;
|
||||
|
@ -151,7 +154,7 @@ public class PlaylistsUtil {
|
|||
}
|
||||
|
||||
@NonNull
|
||||
private static ContentValues[] makeInsertItems(@NonNull final List<Song> songs, final int offset, int len, final int base) {
|
||||
public static ContentValues[] makeInsertItems(@NonNull final List<Song> songs, final int offset, int len, final int base) {
|
||||
if (offset + len > songs.size()) {
|
||||
len = songs.size() - offset;
|
||||
}
|
||||
|
@ -161,7 +164,7 @@ public class PlaylistsUtil {
|
|||
for (int i = 0; i < len; i++) {
|
||||
contentValues[i] = new ContentValues();
|
||||
contentValues[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base + offset + i);
|
||||
contentValues[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, songs.get(offset + i).getAlbumId());
|
||||
contentValues[i].put(MediaStore.Audio.Playlists.Members.AUDIO_ID, songs.get(offset + i).getId());
|
||||
}
|
||||
return contentValues;
|
||||
}
|
||||
|
@ -235,8 +238,7 @@ public class PlaylistsUtil {
|
|||
|
||||
public static String getNameForPlaylist(@NonNull final Context context, final long id) {
|
||||
try {
|
||||
Cursor cursor = context.getContentResolver().query(
|
||||
EXTERNAL_CONTENT_URI,
|
||||
Cursor cursor = context.getContentResolver().query(EXTERNAL_CONTENT_URI,
|
||||
new String[]{MediaStore.Audio.PlaylistsColumns.NAME},
|
||||
BaseColumns._ID + "=?",
|
||||
new String[]{String.valueOf(id)},
|
||||
|
@ -255,8 +257,20 @@ public class PlaylistsUtil {
|
|||
return "";
|
||||
}
|
||||
|
||||
public static Observable<File> savePlaylist(Context context, Playlist playlist) {
|
||||
return M3UWriter.Companion.write(context, new File(Environment.getExternalStorageDirectory(), "Playlists"), playlist);
|
||||
public static Observable<File> savePlaylist(Context context, Playlist playlist) throws IOException {
|
||||
return M3UWriter.write(context, new File(Environment.getExternalStorageDirectory(), "Playlists"), playlist);
|
||||
}
|
||||
|
||||
private static boolean doesPlaylistExist(@NonNull Context context, @NonNull final String selection, @NonNull final String[] values) {
|
||||
Cursor cursor = context.getContentResolver().query(EXTERNAL_CONTENT_URI,
|
||||
new String[]{}, selection, values, null);
|
||||
|
||||
boolean exists = false;
|
||||
if (cursor != null) {
|
||||
exists = cursor.getCount() != 0;
|
||||
cursor.close();
|
||||
}
|
||||
return exists;
|
||||
}
|
||||
|
||||
}
|
|
@ -30,8 +30,8 @@ class MaterialButtonTextColor @JvmOverloads constructor(context: Context, attrs:
|
|||
init {
|
||||
setTextColor(MaterialValueHelper.getPrimaryTextColor(getContext(), ColorUtil.isColorLight(ThemeStore.primaryColor(getContext()))))
|
||||
iconTint = ColorStateList.valueOf(ATHUtil.resolveColor(context, R.attr.iconColor))
|
||||
iconPadding = RetroUtil.convertDpToPixel(16f, getContext()).toInt()
|
||||
rippleColor = ColorStateList.valueOf(ColorUtil.withAlpha(ThemeStore.accentColor(context), 0.4f))
|
||||
minHeight = RetroUtil.convertDpToPixel(52f, context).toInt()
|
||||
//minHeight = RetroUtil.convertDpToPixel(42f, context).toInt()
|
||||
iconSize = RetroUtil.convertDpToPixel(20f, context).toInt()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
android:orientation="vertical"
|
||||
android:paddingTop="8dp">
|
||||
|
||||
<code.name.monkey.appthemehelper.common.views.ATESecondaryTextView
|
||||
<code.name.monkey.appthemehelper.common.views.ATEPrimaryTextView
|
||||
android:id="@+id/bannerTitle"
|
||||
style="@style/SubTitleTextAppearance"
|
||||
android:padding="12dp"
|
||||
|
|
|
@ -86,11 +86,12 @@
|
|||
style="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:ellipsize="marquee"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/md_white_1000"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/artistImage"
|
||||
|
|
|
@ -27,11 +27,12 @@
|
|||
style="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:ellipsize="marquee"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/md_white_1000"
|
||||
app:layout_constraintEnd_toStartOf="@+id/songFavourite"
|
||||
app:layout_constraintStart_toEndOf="@+id/playerMenu"
|
||||
|
@ -45,7 +46,7 @@
|
|||
android:alpha="0.75"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:maxLines="2"
|
||||
android:maxLines="1"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:textColor="@color/md_white_1000"
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
tools:ignore="MissingPrefix">
|
||||
|
||||
<LinearLayout
|
||||
|
@ -14,15 +14,13 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<code.name.monkey.retromusic.views.CircularImageView
|
||||
android:id="@+id/userImage"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_width="38dp"
|
||||
android:layout_height="38dp"
|
||||
android:layout_weight="0"
|
||||
app:civ_border="false" />
|
||||
|
||||
|
@ -84,13 +82,13 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:textColor="@color/md_grey_200"
|
||||
style="@style/TextAppearance.MaterialComponents.Overline"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:text="Upgrade to premium" />
|
||||
android:text="Upgrade to premium"
|
||||
android:textColor="@color/md_grey_200" />
|
||||
|
||||
<TextView
|
||||
style="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
|
@ -98,15 +96,15 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:textColor="@color/md_white_1000"
|
||||
android:text="@string/buy_pro" />
|
||||
android:text="@string/buy_pro"
|
||||
android:textColor="@color/md_white_1000" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:src="@drawable/promotional"
|
||||
android:contentDescription="TODO" />
|
||||
android:contentDescription="TODO"
|
||||
android:src="@drawable/promotional" />
|
||||
</LinearLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
|
@ -134,24 +132,30 @@
|
|||
android:text="@string/action_share"
|
||||
app:icon="@drawable/ic_share_white_24dp" />
|
||||
|
||||
<code.name.monkey.retromusic.views.MaterialButtonTextColor
|
||||
android:id="@+id/actionBugReport"
|
||||
style="@style/OptionButtonsStyle"
|
||||
android:text="@string/report_bug"
|
||||
app:icon="@drawable/ic_bug_report_white_24dp" />
|
||||
|
||||
<code.name.monkey.retromusic.views.MaterialButtonTextColor
|
||||
android:id="@+id/actionAbout"
|
||||
style="@style/OptionButtonsStyle"
|
||||
android:text="@string/action_about"
|
||||
app:icon="@drawable/ic_help_white_24dp" />
|
||||
|
||||
<code.name.monkey.retromusic.views.MaterialButtonTextColor
|
||||
android:id="@+id/actionRate"
|
||||
style="@style/OptionButtonsStyle"
|
||||
android:text="@string/rate_app"
|
||||
app:icon="@drawable/ic_star_white_24dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/actionBugReport"
|
||||
style="@style/OptionButtonsTextStyle"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/report_bug"
|
||||
tools:textColor="@color/md_red_A400" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/actionAbout"
|
||||
style="@style/OptionButtonsTextStyle"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/action_about"
|
||||
tools:textColor="@color/md_red_A400" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
|
@ -135,6 +135,14 @@
|
|||
<item name="android:gravity">center_vertical</item>
|
||||
<item name="android:paddingBottom">12dp</item>
|
||||
<item name="android:paddingTop">12dp</item>
|
||||
<item name="iconSize">12dp</item>
|
||||
</style>
|
||||
|
||||
<style name="OptionButtonsTextStyle" parent="@style/Widget.MaterialComponents.Button.TextButton">
|
||||
<item name="android:layout_width">wrap_content</item>
|
||||
<item name="android:layout_height">wrap_content</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
<item name="android:textSize">12sp</item>
|
||||
</style>
|
||||
|
||||
<style name="ErrorHandlingTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||
|
|
|
@ -16,6 +16,6 @@ org.gradle.parallel=true
|
|||
jvmArgs='-Xmx2048m'
|
||||
android.useAndroidX=true
|
||||
android.enabelR8=true
|
||||
#android.enableR8.fullMode=true
|
||||
android.enableR8.fullMode=false
|
||||
android.enableJetifier=true
|
||||
android.debug.obsoleteApi=true
|
Loading…
Reference in a new issue