Fix Preference list selection and Favourite Song

main
h4h13 2019-03-09 08:02:29 +05:30
parent 263620310f
commit 9156ec2390
33 changed files with 192 additions and 237 deletions

View File

@ -32,7 +32,7 @@ android {
vectorDrawables.useSupportLibrary = true
applicationId "code.name.monkey.retromusic"
versionCode 299
versionCode 230
versionName '3.1.250'
multiDexEnabled true

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -55,7 +55,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(), PlayerAlbumCoverFragment.Call
}
}
override fun toolbarGet(): Toolbar {
override fun playerToolbar(): Toolbar {
return playerToolbar
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -43,7 +43,7 @@ class TinyPlayerFragment : AbsPlayerFragment(), MusicProgressViewUpdateHelper.Ca
}
override fun toolbarGet(): Toolbar {
override fun playerToolbar(): Toolbar {
return playerToolbar
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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