Code refactor

This commit is contained in:
h4h13 2020-02-12 23:44:19 +05:30
parent d8dc39d293
commit 3a0e130e06
23 changed files with 399 additions and 389 deletions

View file

@ -22,8 +22,8 @@ android {
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
applicationId "code.name.monkey.retromusic" applicationId "code.name.monkey.retromusic"
versionCode 405 versionCode 408
versionName '3.4.900' versionName '3.5.000'
multiDexEnabled true multiDexEnabled true
@ -129,8 +129,8 @@ dependencies {
implementation 'androidx.preference:preference:1.1.0' implementation 'androidx.preference:preference:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.core:core-ktx:1.1.0' implementation 'androidx.core:core-ktx:1.2.0'
implementation 'androidx.fragment:fragment:1.2.0' implementation 'androidx.fragment:fragment:1.2.1'
implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.google.android.material:material:1.2.0-alpha04' implementation 'com.google.android.material:material:1.2.0-alpha04'

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}; } ol { list-style-position: inside; padding-left: 0; padding-right: 0; } li { padding-top: 8px; } </style> </head> <body> <h4>v.3.5.000</h4> <ul> <li>Major code refactor</li> <li></li> </ul> <h4>v3.4.900</h4> <ul> <li>Added playlist search</li> <li>Added Drive mode</li> <li>Added Album and Artist layout change option in library</li> <li>Added Show more album and artist information in details</li> <li>Added Pixel style scroller bar</li> <li>Added current now playing share</li> <li>Fix font issues and colors in some places</li> <li>Improved Full now playing theme</li> </ul> <h4>v3.4.850</h4> <ul> <li>Added new theme called circle</li> <li>Added tiny color card style for home artists</li> <li>Added extra track info details to now playing themes</li> <li>Added scroll animation</li> <li>Added smooth transition animations 🤔</li> <li>Added current playing tab options for Bottom Navigation View</li> <li>Added search in genre</li> <li>Improved selecting feedback effect(ripple with corners)</li> <li>Fix bugs & crashes</li> <li>Fix crashing on lyrics</li> <li>Fix genre details last song is under mini player</li> <li>Fix colors mistakes and font sizes</li> <li>Fix slider jumping while scrolling in now playing themes</li> </ul> <h4>v3.4.800</h4> <ul> <li>Improved dark theme colors and Follow system theme</li> <li>Rounded rectangle ripple for BottomNavigationView</li> <li>Follow sleep timer dialog checkbox color as accent</li> <li>Added song list selection for Album and Artist details</li> <li>Fixed Toolbar popup text color when selecting songs</li> </ul> <h4>v3.4.700</h4> <ul> <li>Added splash screen(for app loading time)</li> <li>Updated dark theme colors</li> <li>Added circular progress view</li> <li>Hiding year if not showing</li> </ul> <h4>v3.4.600</h4> <ul> <li>Fix notification layout height</li> <li>Fix folder list last item not showing</li> <li>Added auto hide/ show controls according to first and last item</li> </ul> <h4>v3.4.500</h4> <ul> <li>Added peak theme</li> <li>Added app rating dialog</li> <li>Fix song name scrolling in now playing themes if it's long</li> <li>Fix playing queue last item hiding FAB</li> <li>Added desaturated color option for dark mode</li> <li>Fix slow search loading</li> <li>Fix last added slow loading</li> <li>Fix home banner toolbar corner</li> <li>Fix home crashing when switching between two tabs</li> <li>Fix remaining time in playing queue</li> <li>Fix font not applied for some components</li> <li>Fix crashing on album details sorting</li> <li>Fixed lot of internal bugs</li> <li>Fix dialog expand</li> <li>Fix list card color</li> <li>Removed SlidingUpPanel to replace with BottomSheet</li> <li>Removed color theme as per material design guidelines</li> <li>Removed classic theme(We're bringing back)</li> <li>Replace line switch to Material Switch in settings</li> <li>Performance improved</li> <li>Updated internal libraries</li> <li>Updated translation</li> <li>Limiting the use of Theme engine for making use of system colors</li> <li>Change home icon from the user icon</li> <li>Corrected all toolbar with elevation when scrolling</li> </ul> <p>If you see entire app white or dark or black select same theme in settings to fix </p> <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}; } ol { list-style-position: inside; padding-left: 0; padding-right: 0; } li { padding-top: 8px; } </style> </head> <body> <h4>v.3.5.000</h4> <ul> <li>Major code refactor for Album and Artist loading</li> </ul> <h4>v3.4.900</h4> <ul> <li>Added playlist search</li> <li>Added Drive mode</li> <li>Added Album and Artist layout change option in library</li> <li>Added Show more album and artist information in details</li> <li>Added Pixel style scroller bar</li> <li>Added current now playing share</li> <li>Fix font issues and colors in some places</li> <li>Improved Full now playing theme</li> </ul> <h4>v3.4.850</h4> <ul> <li>Added new theme called circle</li> <li>Added tiny color card style for home artists</li> <li>Added extra track info details to now playing themes</li> <li>Added scroll animation</li> <li>Added smooth transition animations 🤔</li> <li>Added current playing tab options for Bottom Navigation View</li> <li>Added search in genre</li> <li>Improved selecting feedback effect(ripple with corners)</li> <li>Fix bugs & crashes</li> <li>Fix crashing on lyrics</li> <li>Fix genre details last song is under mini player</li> <li>Fix colors mistakes and font sizes</li> <li>Fix slider jumping while scrolling in now playing themes</li> </ul> <h4>v3.4.800</h4> <ul> <li>Improved dark theme colors and Follow system theme</li> <li>Rounded rectangle ripple for BottomNavigationView</li> <li>Follow sleep timer dialog checkbox color as accent</li> <li>Added song list selection for Album and Artist details</li> <li>Fixed Toolbar popup text color when selecting songs</li> </ul> <h4>v3.4.700</h4> <ul> <li>Added splash screen(for app loading time)</li> <li>Updated dark theme colors</li> <li>Added circular progress view</li> <li>Hiding year if not showing</li> </ul> <h4>v3.4.600</h4> <ul> <li>Fix notification layout height</li> <li>Fix folder list last item not showing</li> <li>Added auto hide/ show controls according to first and last item</li> </ul> <h4>v3.4.500</h4> <ul> <li>Added peak theme</li> <li>Added app rating dialog</li> <li>Fix song name scrolling in now playing themes if it's long</li> <li>Fix playing queue last item hiding FAB</li> <li>Added desaturated color option for dark mode</li> <li>Fix slow search loading</li> <li>Fix last added slow loading</li> <li>Fix home banner toolbar corner</li> <li>Fix home crashing when switching between two tabs</li> <li>Fix remaining time in playing queue</li> <li>Fix font not applied for some components</li> <li>Fix crashing on album details sorting</li> <li>Fixed lot of internal bugs</li> <li>Fix dialog expand</li> <li>Fix list card color</li> <li>Removed SlidingUpPanel to replace with BottomSheet</li> <li>Removed color theme as per material design guidelines</li> <li>Removed classic theme(We're bringing back)</li> <li>Replace line switch to Material Switch in settings</li> <li>Performance improved</li> <li>Updated internal libraries</li> <li>Updated translation</li> <li>Limiting the use of Theme engine for making use of system colors</li> <li>Change home icon from the user icon</li> <li>Corrected all toolbar with elevation when scrolling</li> </ul> <p>If you see entire app white or dark or black select same theme in settings to fix </p> <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

@ -31,7 +31,7 @@ object Constants {
const val FAQ_LINK = "https://github.com/h4h13/RetroMusicPlayer/blob/master/FAQ.md" const val FAQ_LINK = "https://github.com/h4h13/RetroMusicPlayer/blob/master/FAQ.md"
const val PINTEREST = "https://in.pinterest.com/retromusicapp/" const val PINTEREST = "https://in.pinterest.com/retromusicapp/"
const val BASE_SELECTION = MediaStore.Audio.AudioColumns.IS_MUSIC + "=1" + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''" const val baseSelection = MediaStore.Audio.AudioColumns.IS_MUSIC + "=1" + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''"
val baseProjection = arrayOf(BaseColumns._ID, // 0 val baseProjection = arrayOf(BaseColumns._ID, // 0
MediaStore.Audio.AudioColumns.TITLE, // 1 MediaStore.Audio.AudioColumns.TITLE, // 1

View file

@ -29,8 +29,8 @@ import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.bottomsheets.BottomSheet import com.afollestad.materialdialogs.bottomsheets.BottomSheet
import com.afollestad.materialdialogs.list.listItems import com.afollestad.materialdialogs.list.listItems
import java.io.File import java.io.File
import java.util.* import java.util.Collections
import kotlin.collections.ArrayList import java.util.Comparator
class BlacklistFolderChooserDialog : DialogFragment() { class BlacklistFolderChooserDialog : DialogFragment() {
@ -40,7 +40,6 @@ class BlacklistFolderChooserDialog : DialogFragment() {
private var canGoUp = false private var canGoUp = false
private var callback: FolderCallback? = null private var callback: FolderCallback? = null
private fun contentsArray(): List<String> { private fun contentsArray(): List<String> {
if (parentContents == null) { if (parentContents == null) {
return if (canGoUp) { return if (canGoUp) {
@ -81,7 +80,11 @@ class BlacklistFolderChooserDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
var savedInstanceStateFinal = savedInstanceState var savedInstanceStateFinal = savedInstanceState
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
ActivityCompat.checkSelfPermission(requireActivity(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.checkSelfPermission(
requireActivity(),
Manifest.permission.READ_EXTERNAL_STORAGE
) != PackageManager.PERMISSION_GRANTED
) {
return MaterialDialog(requireActivity(), BottomSheet(LayoutMode.WRAP_CONTENT)).show { return MaterialDialog(requireActivity(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
title(R.string.md_error_label) title(R.string.md_error_label)
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)

View file

@ -10,21 +10,19 @@ enum class NowPlayingScreen constructor(
@param:DrawableRes @field:DrawableRes val drawableResId: Int, @param:DrawableRes @field:DrawableRes val drawableResId: Int,
val id: Int val id: Int
) { ) {
NORMAL(R.string.normal, R.drawable.np_normal, 0),
FLAT(R.string.flat, R.drawable.np_flat, 1),
FIT(R.string.fit, R.drawable.np_fit, 12),
TINY(R.string.tiny, R.drawable.np_tiny, 7),
PEAK(R.string.peak, R.drawable.np_peak, 14),
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), BLUR(R.string.blur, R.drawable.np_blur, 4),
BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9), BLUR_CARD(R.string.blur_card, R.drawable.np_blur_card, 9),
CARD(R.string.card, R.drawable.np_card, 6), CARD(R.string.card, R.drawable.np_card, 6),
COLOR(R.string.color, R.drawable.np_color, 5), COLOR(R.string.color, R.drawable.np_color, 5),
CIRCLE(R.string.circle, R.drawable.np_minimalistic_circle, 15), CIRCLE(R.string.circle, R.drawable.np_minimalistic_circle, 15),
FIT(R.string.fit, R.drawable.np_fit, 12),
FLAT(R.string.flat, R.drawable.np_flat, 1),
FULL(R.string.full, R.drawable.np_full, 2), FULL(R.string.full, R.drawable.np_full, 2),
MATERIAL(R.string.material, R.drawable.np_material, 11), MATERIAL(R.string.material, R.drawable.np_material, 11),
NORMAL(R.string.normal, R.drawable.np_normal, 0),
PEAK(R.string.peak, R.drawable.np_peak, 14),
PLAIN(R.string.plain, R.drawable.np_plain, 3), PLAIN(R.string.plain, R.drawable.np_plain, 3),
SIMPLE(R.string.simple, R.drawable.np_simple, 8), SIMPLE(R.string.simple, R.drawable.np_simple, 8),
TINY(R.string.tiny, R.drawable.np_tiny, 7),
} }

View file

@ -99,7 +99,7 @@ class BlurPlayerFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPrefer
private fun updateBlur() { private fun updateBlur() {
val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext()) val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext())
.getInt(PreferenceUtil.NEW_BLUR_AMOUNT, 25) .getInt(PreferenceUtil.NEW_BLUR_AMOUNT, 25)
colorBackground!!.clearColorFilter() colorBackground?.clearColorFilter()
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong) SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
.checkIgnoreMediaStore(requireContext()) .checkIgnoreMediaStore(requireContext())
.generatePalette(requireContext()).build() .generatePalette(requireContext()).build()
@ -109,7 +109,7 @@ class BlurPlayerFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPrefer
.into(object : RetroMusicColoredTarget(colorBackground) { .into(object : RetroMusicColoredTarget(colorBackground) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
if (color == defaultFooterColor) { if (color == defaultFooterColor) {
colorBackground!!.setColorFilter(color) colorBackground?.setColorFilter(color)
} }
} }
}) })

View file

@ -13,9 +13,9 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
import code.name.monkey.retromusic.glide.AlbumGlideRequest
import code.name.monkey.retromusic.glide.BlurTransformation import code.name.monkey.retromusic.glide.BlurTransformation
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget 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.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
@ -53,7 +53,7 @@ class CardBlurFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPreferen
override fun onColorChanged(color: Int) { override fun onColorChanged(color: Int) {
playbackControlsFragment.setDark(color) playbackControlsFragment.setDark(color)
lastColor = color lastColor = color
callbacks!!.onPaletteColorChanged() callbacks?.onPaletteColorChanged()
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity) ToolbarContentTintHelper.colorizeToolbar(playerToolbar, Color.WHITE, activity)
playerToolbar.setTitleTextColor(Color.WHITE) playerToolbar.setTitleTextColor(Color.WHITE)
@ -127,10 +127,19 @@ class CardBlurFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPreferen
} }
private fun updateBlur() { private fun updateBlur() {
colorBackground?.clearColorFilter()
val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext()) val blurAmount = PreferenceManager.getDefaultSharedPreferences(requireContext())
.getInt(PreferenceUtil.NEW_BLUR_AMOUNT, 25) .getInt(PreferenceUtil.NEW_BLUR_AMOUNT, 25)
colorBackground!!.clearColorFilter() AlbumGlideRequest.Builder.from(Glide.with(requireContext()), MusicPlayerRemote.currentSong.albumId)
SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong) .generatePalette(requireContext())
.build()
.transform(BlurTransformation.Builder(requireContext()).blurRadius(blurAmount.toFloat()).build())
.into(object : RetroMusicColoredTarget(colorBackground) {
override fun onColorReady(color: Int) {
}
})
//colorBackground?.clearColorFilter()
/*SongGlideRequest.Builder.from(Glide.with(requireActivity()), MusicPlayerRemote.currentSong)
.checkIgnoreMediaStore(requireContext()) .checkIgnoreMediaStore(requireContext())
.generatePalette(requireContext()).build() .generatePalette(requireContext()).build()
.transform(BlurTransformation.Builder(requireContext()).blurRadius(blurAmount.toFloat()).build()) .transform(BlurTransformation.Builder(requireContext()).blurRadius(blurAmount.toFloat()).build())
@ -138,11 +147,9 @@ class CardBlurFragment : AbsPlayerFragment(), SharedPreferences.OnSharedPreferen
//.override(320, 480) //.override(320, 480)
.into(object : RetroMusicColoredTarget(colorBackground) { .into(object : RetroMusicColoredTarget(colorBackground) {
override fun onColorReady(color: Int) { override fun onColorReady(color: Int) {
if (color == defaultFooterColor) {
colorBackground!!.setColorFilter(color)
}
} }
}) })*/
} }
override fun onResume() { override fun onResume() {

View file

@ -18,8 +18,8 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.ViewUtil import code.name.monkey.retromusic.util.ViewUtil
import code.name.monkey.retromusic.views.DrawableGradient import code.name.monkey.retromusic.views.DrawableGradient
import kotlinx.android.synthetic.main.fragment_player.* import kotlinx.android.synthetic.main.fragment_player.colorGradientBackground
import kotlinx.android.synthetic.main.fragment_player.playerToolbar
class PlayerFragment : AbsPlayerFragment() { class PlayerFragment : AbsPlayerFragment() {
@ -30,18 +30,21 @@ class PlayerFragment : AbsPlayerFragment() {
private lateinit var playbackControlsFragment: PlayerPlaybackControlsFragment private lateinit var playbackControlsFragment: PlayerPlaybackControlsFragment
private var valueAnimator: ValueAnimator? = null private var valueAnimator: ValueAnimator? = null
private fun colorize(i: Int) { private fun colorize(i: Int) {
if (valueAnimator != null) { if (valueAnimator != null) {
valueAnimator?.cancel() valueAnimator?.cancel()
} }
valueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), ATHUtil.resolveColor(requireContext(), R.attr.colorSurface), i) valueAnimator = ValueAnimator.ofObject(ArgbEvaluator(), lastColor, i)
valueAnimator?.addUpdateListener { animation -> valueAnimator?.addUpdateListener { animation ->
if (isAdded) { if (isAdded) {
val drawable = DrawableGradient(GradientDrawable.Orientation.TOP_BOTTOM, val drawable = DrawableGradient(
intArrayOf(animation.animatedValue as Int, GradientDrawable.Orientation.TOP_BOTTOM,
ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)), 0) intArrayOf(
animation.animatedValue as Int,
ATHUtil.resolveColor(requireContext(), R.attr.colorSurface)
), 0
)
colorGradientBackground?.background = drawable colorGradientBackground?.background = drawable
} }
} }
@ -70,7 +73,11 @@ class PlayerFragment : AbsPlayerFragment() {
lastColor = color lastColor = color
callbacks?.onPaletteColorChanged() callbacks?.onPaletteColorChanged()
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.colorControlNormal), requireActivity()) ToolbarContentTintHelper.colorizeToolbar(
playerToolbar,
ATHUtil.resolveColor(context, R.attr.colorControlNormal),
requireActivity()
)
if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) { if (PreferenceUtil.getInstance(requireContext()).adaptiveColor) {
colorize(color) colorize(color)
@ -88,9 +95,10 @@ class PlayerFragment : AbsPlayerFragment() {
toggleFavorite(MusicPlayerRemote.currentSong) toggleFavorite(MusicPlayerRemote.currentSong)
} }
override fun onCreateView(
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? { savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_player, container, false) return inflater.inflate(R.layout.fragment_player, container, false)
} }
@ -101,19 +109,24 @@ class PlayerFragment : AbsPlayerFragment() {
setUpPlayerToolbar() setUpPlayerToolbar()
} }
private fun setUpSubFragments() { private fun setUpSubFragments() {
playbackControlsFragment = childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment playbackControlsFragment =
val playerAlbumCoverFragment = childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as PlayerPlaybackControlsFragment
val playerAlbumCoverFragment =
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
playerAlbumCoverFragment.setCallbacks(this) playerAlbumCoverFragment.setCallbacks(this)
} }
private fun setUpPlayerToolbar() { private fun setUpPlayerToolbar() {
playerToolbar.inflateMenu(R.menu.menu_player) playerToolbar.inflateMenu(R.menu.menu_player)
playerToolbar.setNavigationOnClickListener {requireActivity().onBackPressed() } playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
playerToolbar.setOnMenuItemClickListener(this) playerToolbar.setOnMenuItemClickListener(this)
ToolbarContentTintHelper.colorizeToolbar(playerToolbar, ATHUtil.resolveColor(context, R.attr.colorControlNormal), requireActivity()) ToolbarContentTintHelper.colorizeToolbar(
playerToolbar,
ATHUtil.resolveColor(context, R.attr.colorControlNormal),
requireActivity()
)
} }
override fun onServiceConnected() { override fun onServiceConnected() {

View file

@ -20,11 +20,9 @@ import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
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.RetroColorUtil import code.name.monkey.retromusic.util.RetroColorUtil
import com.bumptech.glide.request.animation.GlideAnimation import com.bumptech.glide.request.animation.GlideAnimation
abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) { abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(view) {
protected val defaultFooterColor: Int protected val defaultFooterColor: Int
@ -40,15 +38,17 @@ abstract class RetroMusicColoredTarget(view: ImageView) : BitmapPaletteTarget(vi
onColorReady(defaultFooterColor) onColorReady(defaultFooterColor)
} }
override fun onResourceReady(resource: BitmapPaletteWrapper?, glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?) { override fun onResourceReady(
resource: BitmapPaletteWrapper?,
glideAnimation: GlideAnimation<in BitmapPaletteWrapper>?
) {
super.onResourceReady(resource, glideAnimation) super.onResourceReady(resource, glideAnimation)
val defaultColor = defaultFooterColor val defaultColor = defaultFooterColor
resource?.let { resource?.let {
onColorReady(if (PreferenceUtil.getInstance(getView().context).isDominantColor) onColorReady(
RetroColorUtil.getDominantColor(it.bitmap, defaultColor) RetroColorUtil.getColor(it.palette, defaultColor)
else )
RetroColorUtil.getColor(it.palette, defaultColor))
} }
} }
} }

View file

@ -19,7 +19,7 @@ import android.database.Cursor
import android.net.Uri import android.net.Uri
import android.provider.BaseColumns import android.provider.BaseColumns
import android.provider.MediaStore.Audio.Genres import android.provider.MediaStore.Audio.Genres
import code.name.monkey.retromusic.Constants.BASE_SELECTION import code.name.monkey.retromusic.Constants.baseSelection
import code.name.monkey.retromusic.Constants.baseProjection import code.name.monkey.retromusic.Constants.baseProjection
import code.name.monkey.retromusic.model.Genre import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
@ -94,7 +94,7 @@ object GenreLoader {
try { try {
return context.contentResolver.query( return context.contentResolver.query(
Genres.Members.getContentUri("external", genreId.toLong()), Genres.Members.getContentUri("external", genreId.toLong()),
baseProjection, BASE_SELECTION, null, PreferenceUtil.getInstance(context).songSortOrder) baseProjection, baseSelection, null, PreferenceUtil.getInstance(context).songSortOrder)
} catch (e: SecurityException) { } catch (e: SecurityException) {
return null return null
} }

View file

@ -18,7 +18,7 @@ import android.content.Context
import android.database.Cursor import android.database.Cursor
import android.provider.MediaStore import android.provider.MediaStore
import android.provider.MediaStore.Audio.AudioColumns import android.provider.MediaStore.Audio.AudioColumns
import code.name.monkey.retromusic.Constants.BASE_SELECTION import code.name.monkey.retromusic.Constants.baseSelection
import code.name.monkey.retromusic.model.AbsCustomPlaylist import code.name.monkey.retromusic.model.AbsCustomPlaylist
import code.name.monkey.retromusic.model.Playlist import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.PlaylistSong import code.name.monkey.retromusic.model.PlaylistSong
@ -104,7 +104,7 @@ object PlaylistSongsLoader {
MediaStore.Audio.Playlists.Members._ID,//11 MediaStore.Audio.Playlists.Members._ID,//11
AudioColumns.COMPOSER AudioColumns.COMPOSER
)// 12 )// 12
, BASE_SELECTION, null, , baseSelection, null,
MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER MediaStore.Audio.Playlists.Members.DEFAULT_SORT_ORDER
) )
} catch (e: SecurityException) { } catch (e: SecurityException) {

View file

@ -18,10 +18,9 @@ import android.content.Context
import android.database.Cursor import android.database.Cursor
import android.provider.MediaStore import android.provider.MediaStore
import android.provider.MediaStore.Audio.AudioColumns import android.provider.MediaStore.Audio.AudioColumns
import code.name.monkey.retromusic.Constants.BASE_SELECTION
import code.name.monkey.retromusic.Constants.baseProjection import code.name.monkey.retromusic.Constants.baseProjection
import code.name.monkey.retromusic.Constants.baseSelection
import code.name.monkey.retromusic.model.Song import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.providers.BlacklistStore
import code.name.monkey.retromusic.util.PreferenceUtil import code.name.monkey.retromusic.util.PreferenceUtil
import java.util.ArrayList import java.util.ArrayList
@ -61,7 +60,7 @@ object SongLoader {
return getSongs(cursor) return getSongs(cursor)
} }
fun getSong( private fun getSong(
cursor: Cursor? cursor: Cursor?
): Song { ): Song {
val song: Song val song: Song
@ -84,71 +83,70 @@ object SongLoader {
cursor: Cursor cursor: Cursor
): Song = Song.fromCursor(cursor) ): Song = Song.fromCursor(cursor)
@JvmStatic
@JvmOverloads @JvmOverloads
fun makeSongCursor( fun makeSongCursor(
context: Context, context: Context,
selection: String?, selectionString: String?,
selectionValues: Array<String>?, selectionValuesArray: Array<String>?,
sortOrder: String = PreferenceUtil.getInstance(context).songSortOrder sortOrder: String = PreferenceUtil.getInstance(context).songSortOrder
): Cursor? { ): Cursor {
var selectionFinal = selection var selectionValues: Array<String>? = arrayOf()
var selectionValuesFinal = selectionValues var selection = if (selectionString != null && selectionString.trim() != "") {
selectionFinal = if (selection != null && selection.trim { it <= ' ' } != "") { "$baseSelection AND $selectionString"
"$BASE_SELECTION AND $selectionFinal"
} else { } else {
BASE_SELECTION baseSelection
} }
// Blacklist // Blacklist
val paths = BlacklistStore.getInstance(context).paths /*val paths = BlacklistStore.getInstance(context).paths
if (paths.isNotEmpty()) { if (paths.isNotEmpty()) {
selectionFinal = generateBlacklistSelection(selectionFinal, paths.size) selection = generateBlacklistSelection(selection, paths.size)
selectionValuesFinal = addBlacklistSelectionValues(selectionValuesFinal, paths) selectionValues = addBlacklistSelectionValues(selectionValuesArray, paths)
}*/
if (PreferenceUtil.getInstance(context).filterLength != 0) {
selection =
"$selection AND ${MediaStore.Audio.Media.DURATION} >= ${PreferenceUtil.getInstance(context).filterLength * 1000}"
} }
try { return context.contentResolver.query(
return context.contentResolver.query( MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, baseProjection,
baseProjection, selection,
selectionFinal + " AND " + MediaStore.Audio.Media.DURATION + ">= " + (PreferenceUtil.getInstance( selectionValuesArray,
context sortOrder
).filterLength * 1000), )
selectionValuesFinal, ?: throw IllegalStateException("Unable to query ${MediaStore.Audio.Media.EXTERNAL_CONTENT_URI}, system returned null.")
sortOrder
)
} catch (e: SecurityException) {
return null
}
}
private fun generateBlacklistSelection(
selection: String?,
pathCount: Int
): String {
val newSelection = StringBuilder(
if (selection != null && selection.trim { it <= ' ' } != "") "$selection AND " else "")
newSelection.append(AudioColumns.DATA + " NOT LIKE ?")
for (i in 0 until pathCount - 1) {
newSelection.append(" AND " + AudioColumns.DATA + " NOT LIKE ?")
}
return newSelection.toString()
}
private fun addBlacklistSelectionValues(
selectionValues: Array<String>?,
paths: ArrayList<String>
): Array<String>? {
var selectionValuesFinal = selectionValues
if (selectionValuesFinal == null) {
selectionValuesFinal = emptyArray()
}
val newSelectionValues = Array(selectionValuesFinal.size + paths.size) {
"n = $it"
}
System.arraycopy(selectionValuesFinal, 0, newSelectionValues, 0, selectionValuesFinal.size)
for (i in selectionValuesFinal.size until newSelectionValues.size) {
newSelectionValues[i] = paths[i - selectionValuesFinal.size] + "%"
}
return newSelectionValues
} }
} }
fun generateBlacklistSelection(
selection: String?,
pathCount: Int
): String {
val newSelection = StringBuilder(
if (selection != null && selection.trim { it <= ' ' } != "") "$selection AND " else "")
newSelection.append(AudioColumns.DATA + " NOT LIKE ?")
for (i in 0 until pathCount - 1) {
newSelection.append(" AND " + AudioColumns.DATA + " NOT LIKE ?")
}
return newSelection.toString()
}
fun addBlacklistSelectionValues(
selectionValues: Array<String>?,
paths: ArrayList<String>
): Array<String>? {
var selectionValuesFinal = selectionValues
if (selectionValuesFinal == null) {
selectionValuesFinal = emptyArray()
}
val newSelectionValues = Array(selectionValuesFinal.size + paths.size) {
"n = $it"
}
System.arraycopy(selectionValuesFinal, 0, newSelectionValues, 0, selectionValuesFinal.size)
for (i in selectionValuesFinal.size until newSelectionValues.size) {
newSelectionValues[i] = paths[i - selectionValuesFinal.size] + "%"
}
return newSelectionValues
}

View file

@ -27,52 +27,6 @@ class Artist(
var albumCount: Int = 0 var albumCount: Int = 0
) { ) {
/*val albums: ArrayList<Album>?
val id: Int
get() = safeGetFirstAlbum().artistId
val name: String
get() {
val name = safeGetFirstAlbum().artist
return if (MusicUtil.isArtistNameUnknown(name)) {
UNKNOWN_ARTIST_DISPLAY_NAME
} else name!!
}
val songCount: Int
get() {
var songCount = 0
for (album in albums!!) {
songCount += album.songCount
}
return songCount
}
val albumCount: Int
get() = albums!!.size
val songs: ArrayList<Song>
get() {
val songs = ArrayList<Song>()
for (album in albums!!) {
//songs.addAll(album.songs!!)
}
return songs
}
constructor(albums: ArrayList<Album>) {
this.albums = albums
}
constructor() {
this.albums = ArrayList()
}
fun safeGetFirstAlbum(): Album {
return if (albums!!.isEmpty()) Album() else albums[0]
}
*/
companion object { companion object {
fun fromCursor(cursor: Cursor): Artist { fun fromCursor(cursor: Cursor): Artist {

View file

@ -41,7 +41,12 @@ class BlacklistPreference : ATEDialogPreference {
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(
context,
attrs,
defStyleAttr,
defStyleRes
)
init { init {
icon?.setColorFilter(ThemeStore.textColorSecondary(context), PorterDuff.Mode.SRC_IN) icon?.setColorFilter(ThemeStore.textColorSecondary(context), PorterDuff.Mode.SRC_IN)
@ -55,23 +60,23 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
} }
} }
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val blacklistFolderChooserDialog = childFragmentManager.findFragmentByTag("FOLDER_CHOOSER") as BlacklistFolderChooserDialog? val blacklistFolderChooserDialog =
childFragmentManager.findFragmentByTag("FOLDER_CHOOSER") as BlacklistFolderChooserDialog?
blacklistFolderChooserDialog?.setCallback(this) blacklistFolderChooserDialog?.setCallback(this)
refreshBlacklistData() refreshBlacklistData()
return MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show { return MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
title(code.name.monkey.retromusic.R.string.blacklist) title(R.string.blacklist)
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
positiveButton(android.R.string.ok) { positiveButton(android.R.string.ok) {
dismiss() dismiss()
} }
neutralButton(text = getString(R.string.clear_action)) { neutralButton(text = getString(R.string.clear_action)) {
MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show { MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
title(code.name.monkey.retromusic.R.string.clear_blacklist) title(R.string.clear_blacklist)
message(code.name.monkey.retromusic.R.string.do_you_want_to_clear_the_blacklist) message(R.string.do_you_want_to_clear_the_blacklist)
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
positiveButton(code.name.monkey.retromusic.R.string.clear_action) { positiveButton(R.string.clear_action) {
BlacklistStore.getInstance(context).clear() BlacklistStore.getInstance(context).clear()
refreshBlacklistData() refreshBlacklistData()
} }
@ -81,13 +86,20 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
negativeButton(R.string.add_action) { negativeButton(R.string.add_action) {
val dialog = BlacklistFolderChooserDialog.create() val dialog = BlacklistFolderChooserDialog.create()
dialog.setCallback(this@BlacklistPreferenceDialog) dialog.setCallback(this@BlacklistPreferenceDialog)
dialog.show(childFragmentManager, "FOLDER_CHOOSER"); dialog.show(childFragmentManager, "FOLDER_CHOOSER")
} }
listItems(items = paths, waitForPositiveButton = false) { _, _, text -> listItems(items = paths, waitForPositiveButton = false) { _, _, text ->
MaterialDialog(context, BottomSheet(LayoutMode.WRAP_CONTENT)).show { MaterialDialog(requireContext(), BottomSheet(LayoutMode.WRAP_CONTENT)).show {
cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner) cornerRadius(PreferenceUtil.getInstance(requireContext()).dialogCorner)
title(code.name.monkey.retromusic.R.string.remove_from_blacklist) title(R.string.remove_from_blacklist)
message(text = Html.fromHtml(getString(code.name.monkey.retromusic.R.string.do_you_want_to_remove_from_the_blacklist, text))) message(
text = Html.fromHtml(
getString(
R.string.do_you_want_to_remove_from_the_blacklist,
text
)
)
)
positiveButton(code.name.monkey.retromusic.R.string.remove_action) { positiveButton(code.name.monkey.retromusic.R.string.remove_action) {
BlacklistStore.getInstance(context).removePath(File(text.toString())) BlacklistStore.getInstance(context).removePath(File(text.toString()))
refreshBlacklistData() refreshBlacklistData()
@ -108,7 +120,7 @@ class BlacklistPreferenceDialog : DialogFragment(), BlacklistFolderChooserDialog
} }
override fun onFolderSelection(dialog: BlacklistFolderChooserDialog, folder: File) { override fun onFolderSelection(dialog: BlacklistFolderChooserDialog, folder: File) {
BlacklistStore.getInstance(context!!).addPath(folder); BlacklistStore.getInstance(context!!).addPath(folder)
refreshBlacklistData(); refreshBlacklistData()
} }
} }

View file

@ -16,6 +16,7 @@ package code.name.monkey.retromusic.preferences
import android.app.Dialog import android.app.Dialog
import android.content.Context import android.content.Context
import android.content.res.ColorStateList
import android.graphics.PorterDuff import android.graphics.PorterDuff
import android.os.Bundle import android.os.Bundle
import android.util.AttributeSet import android.util.AttributeSet
@ -30,8 +31,12 @@ import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import code.name.monkey.appthemehelper.ThemeStore import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEDialogPreference
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.App import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.fragments.NowPlayingScreen import code.name.monkey.retromusic.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
@ -42,18 +47,23 @@ import com.bumptech.glide.Glide
class NowPlayingScreenPreference : ATEDialogPreference { class NowPlayingScreenPreference : ATEDialogPreference {
constructor(context: Context) : super(context) {} constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {} constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {} constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes) {} constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(
context,
attrs,
defStyleAttr,
defStyleRes
)
private val mLayoutRes = R.layout.preference_dialog_now_playing_screen private val mLayoutRes = R.layout.preference_dialog_now_playing_screen
override fun getDialogLayoutResource(): Int { override fun getDialogLayoutResource(): Int {
return mLayoutRes; return mLayoutRes
} }
init { init {
@ -66,11 +76,9 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
private var viewPagerPosition: Int = 0 private var viewPagerPosition: Int = 0
override fun onPageScrollStateChanged(state: Int) { override fun onPageScrollStateChanged(state: Int) {
} }
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) { override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
} }
override fun onPageSelected(position: Int) { override fun onPageSelected(position: Int) {
@ -78,13 +86,12 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
} }
override fun onDialogClosed(positiveResult: Boolean) { override fun onDialogClosed(positiveResult: Boolean) {
} }
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val view = LayoutInflater.from(activity).inflate(R.layout.preference_dialog_now_playing_screen, null) val view = LayoutInflater.from(activity).inflate(R.layout.preference_dialog_now_playing_screen, null)
val viewPager = view.findViewById<ViewPager>(R.id.now_playing_screen_view_pager) val viewPager = view.findViewById<ViewPager>(R.id.now_playing_screen_view_pager)
?: throw IllegalStateException("Dialog view must contain a ViewPager with id 'now_playing_screen_view_pager'") ?: throw IllegalStateException("Dialog view must contain a ViewPager with id 'now_playing_screen_view_pager'")
viewPager.adapter = NowPlayingScreenAdapter(activity!!) viewPager.adapter = NowPlayingScreenAdapter(activity!!)
viewPager.addOnPageChangeListener(this) viewPager.addOnPageChangeListener(this)
viewPager.pageMargin = ViewUtil.convertDpToPixel(32f, resources).toInt() viewPager.pageMargin = ViewUtil.convertDpToPixel(32f, resources).toInt()
@ -109,24 +116,6 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
} }
} }
private fun isNowPlayingThemes(nowPlayingScreen: NowPlayingScreen): Boolean {
if (nowPlayingScreen == NowPlayingScreen.BLUR_CARD) {
PreferenceUtil.getInstance(requireContext()).resetCarouselEffect()
PreferenceUtil.getInstance(requireContext()).resetCircularAlbumArt()
}
return (nowPlayingScreen == NowPlayingScreen.FULL ||
nowPlayingScreen == NowPlayingScreen.CARD ||
nowPlayingScreen == NowPlayingScreen.PLAIN ||
nowPlayingScreen == NowPlayingScreen.BLUR ||
nowPlayingScreen == NowPlayingScreen.COLOR ||
nowPlayingScreen == NowPlayingScreen.SIMPLE ||
nowPlayingScreen == NowPlayingScreen.BLUR_CARD ||
nowPlayingScreen == NowPlayingScreen.CIRCLE ||
nowPlayingScreen == NowPlayingScreen.ADAPTIVE)
&& !App.isProVersion()
}
companion object { companion object {
fun newInstance(key: String): NowPlayingScreenPreferenceDialog { fun newInstance(key: String): NowPlayingScreenPreferenceDialog {
val bundle = Bundle() val bundle = Bundle()
@ -138,7 +127,7 @@ class NowPlayingScreenPreferenceDialog : PreferenceDialogFragmentCompat(), ViewP
} }
} }
private class NowPlayingScreenAdapter internal constructor(private val context: Context) : PagerAdapter() { private class NowPlayingScreenAdapter(private val context: Context) : PagerAdapter() {
override fun instantiateItem(collection: ViewGroup, position: Int): Any { override fun instantiateItem(collection: ViewGroup, position: Int): Any {
val nowPlayingScreen = NowPlayingScreen.values()[position] val nowPlayingScreen = NowPlayingScreen.values()[position]
@ -148,16 +137,26 @@ private class NowPlayingScreenAdapter internal constructor(private val context:
collection.addView(layout) collection.addView(layout)
val image = layout.findViewById<ImageView>(R.id.image) val image = layout.findViewById<ImageView>(R.id.image)
val proText = layout.findViewById<TextView>(R.id.proText)
val title = layout.findViewById<TextView>(R.id.title) val title = layout.findViewById<TextView>(R.id.title)
Glide.with(context).load(nowPlayingScreen.drawableResId).into(image) Glide.with(context).load(nowPlayingScreen.drawableResId).into(image)
title.setText(nowPlayingScreen.titleRes) title.setText(nowPlayingScreen.titleRes)
if (isNowPlayingThemes(nowPlayingScreen)) {
proText.show()
} else {
proText.hide()
}
val color = ThemeStore.accentColor(context)
proText.backgroundTintList = ColorStateList.valueOf(color)
proText.setTextColor(MaterialValueHelper.getPrimaryTextColor(context,ColorUtil.isColorLight(color)))
return layout return layout
} }
override fun destroyItem(collection: ViewGroup, override fun destroyItem(
position: Int, collection: ViewGroup,
view: Any) { position: Int,
view: Any
) {
collection.removeView(view as View) collection.removeView(view as View)
} }
@ -173,3 +172,18 @@ private class NowPlayingScreenAdapter internal constructor(private val context:
return context.getString(NowPlayingScreen.values()[position].titleRes) return context.getString(NowPlayingScreen.values()[position].titleRes)
} }
} }
fun isNowPlayingThemes(nowPlayingScreen: NowPlayingScreen): Boolean {
return (nowPlayingScreen == NowPlayingScreen.FULL ||
nowPlayingScreen == NowPlayingScreen.CARD ||
nowPlayingScreen == NowPlayingScreen.PLAIN ||
nowPlayingScreen == NowPlayingScreen.BLUR ||
nowPlayingScreen == NowPlayingScreen.COLOR ||
nowPlayingScreen == NowPlayingScreen.SIMPLE ||
nowPlayingScreen == NowPlayingScreen.BLUR_CARD ||
nowPlayingScreen == NowPlayingScreen.CIRCLE ||
nowPlayingScreen == NowPlayingScreen.ADAPTIVE ||
nowPlayingScreen == NowPlayingScreen.MATERIAL ||
nowPlayingScreen == NowPlayingScreen.PEAK)
&& !App.isProVersion()
}

View file

@ -19,10 +19,11 @@ import android.database.Cursor;
import android.os.Environment; import android.os.Environment;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.webkit.MimeTypeMap; import android.webkit.MimeTypeMap;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import code.name.monkey.retromusic.loaders.SongLoader;
import code.name.monkey.retromusic.loaders.SortedCursor;
import code.name.monkey.retromusic.model.Song;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
@ -37,137 +38,9 @@ import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import code.name.monkey.retromusic.loaders.SongLoader;
import code.name.monkey.retromusic.loaders.SortedCursor;
import code.name.monkey.retromusic.model.Song;
public final class FileUtil { public final class FileUtil {
private FileUtil() {
}
public static byte[] readBytes(InputStream stream) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int count;
while ((count = stream.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
stream.close();
return baos.toByteArray();
}
@NonNull
public static ArrayList<Song> matchFilesWithMediaStore(@NonNull Context context,
@Nullable List<File> files) {
return SongLoader.INSTANCE.getSongs(makeSongCursor(context, files));
}
public static String safeGetCanonicalPath(File file) {
try {
return file.getCanonicalPath();
} catch (IOException e) {
e.printStackTrace();
return file.getAbsolutePath();
}
}
@Nullable
public static SortedCursor makeSongCursor(@NonNull final Context context,
@Nullable final List<File> files) {
String selection = null;
String[] paths = null;
if (files != null) {
paths = toPathArray(files);
if (files.size() > 0
&& files.size() < 999) { // 999 is the max amount Androids SQL implementation can handle.
selection =
MediaStore.Audio.AudioColumns.DATA + " IN (" + makePlaceholders(files.size()) + ")";
}
}
Cursor songCursor = SongLoader.INSTANCE.makeSongCursor(context, selection, selection == null ? null : paths);
return songCursor == null ? null
: new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA);
}
private static String makePlaceholders(int len) {
StringBuilder sb = new StringBuilder(len * 2 - 1);
sb.append("?");
for (int i = 1; i < len; i++) {
sb.append(",?");
}
return sb.toString();
}
@Nullable
private static String[] toPathArray(@Nullable List<File> files) {
if (files != null) {
String[] paths = new String[files.size()];
for (int i = 0; i < files.size(); i++) {
/*try {
paths[i] = files.get(i).getCanonicalPath(); // canonical path is important here because we want to compare the path with the media store entry later
} catch (IOException e) {
e.printStackTrace();
paths[i] = files.get(i).getPath();
}*/
paths[i] = safeGetCanonicalPath(files.get(i));
}
return paths;
}
return null;
}
@NonNull
public static List<File> listFiles(@NonNull File directory, @Nullable FileFilter fileFilter) {
List<File> fileList = new LinkedList<>();
File[] found = directory.listFiles(fileFilter);
if (found != null) {
Collections.addAll(fileList, found);
}
return fileList;
}
@NonNull
public static List<File> listFilesDeep(@NonNull File directory, @Nullable FileFilter fileFilter) {
List<File> files = new LinkedList<>();
internalListFilesDeep(files, directory, fileFilter);
return files;
}
@NonNull
public static List<File> listFilesDeep(@NonNull Collection<File> files,
@Nullable FileFilter fileFilter) {
List<File> resFiles = new LinkedList<>();
for (File file : files) {
if (file.isDirectory()) {
internalListFilesDeep(resFiles, file, fileFilter);
} else if (fileFilter == null || fileFilter.accept(file)) {
resFiles.add(file);
}
}
return resFiles;
}
private static void internalListFilesDeep(@NonNull Collection<File> files,
@NonNull File directory, @Nullable FileFilter fileFilter) {
File[] found = directory.listFiles(fileFilter);
if (found != null) {
for (File file : found) {
if (file.isDirectory()) {
internalListFilesDeep(files, file, fileFilter);
} else {
files.add(file);
}
}
}
}
public static boolean fileIsMimeType(File file, String mimeType, MimeTypeMap mimeTypeMap) { public static boolean fileIsMimeType(File file, String mimeType, MimeTypeMap mimeTypeMap) {
if (mimeType == null || mimeType.equals("*/*")) { if (mimeType == null || mimeType.equals("*/*")) {
return true; return true;
@ -209,15 +82,95 @@ public final class FileUtil {
} }
} }
public static String stripExtension(String str) { public static boolean isExternalMemoryAvailable() {
if (str == null) { Boolean isSDPresent = Environment.getExternalStorageState()
return null; .equals(android.os.Environment.MEDIA_MOUNTED);
Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable();
if (isSDSupportedDevice && isSDPresent) {
// yes SD-card is present
return true;
} else {
return false;
// Sorry
} }
int pos = str.lastIndexOf('.'); }
if (pos == -1) {
return str; @NonNull
public static List<File> listFiles(@NonNull File directory, @Nullable FileFilter fileFilter) {
List<File> fileList = new LinkedList<>();
File[] found = directory.listFiles(fileFilter);
if (found != null) {
Collections.addAll(fileList, found);
} }
return str.substring(0, pos); return fileList;
}
@NonNull
public static List<File> listFilesDeep(@NonNull File directory, @Nullable FileFilter fileFilter) {
List<File> files = new LinkedList<>();
internalListFilesDeep(files, directory, fileFilter);
return files;
}
@NonNull
public static List<File> listFilesDeep(@NonNull Collection<File> files,
@Nullable FileFilter fileFilter) {
List<File> resFiles = new LinkedList<>();
for (File file : files) {
if (file.isDirectory()) {
internalListFilesDeep(resFiles, file, fileFilter);
} else if (fileFilter == null || fileFilter.accept(file)) {
resFiles.add(file);
}
}
return resFiles;
}
@Nullable
public static SortedCursor makeSongCursor(@NonNull final Context context,
@Nullable final List<File> files) {
String selection = null;
String[] paths = null;
if (files != null) {
paths = toPathArray(files);
if (files.size() > 0
&& files.size() < 999) { // 999 is the max amount Androids SQL implementation can handle.
selection =
MediaStore.Audio.AudioColumns.DATA + " IN (" + makePlaceholders(files.size()) + ")";
}
}
Cursor songCursor = SongLoader.makeSongCursor(context, selection, selection == null ? null : paths);
return songCursor == null ? null
: new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA);
}
@NonNull
public static ArrayList<Song> matchFilesWithMediaStore(@NonNull Context context,
@Nullable List<File> files) {
return SongLoader.INSTANCE.getSongs(makeSongCursor(context, files));
}
public static String read(File file) throws Exception {
FileInputStream fin = new FileInputStream(file);
String ret = readFromStream(fin);
fin.close();
return ret;
}
public static byte[] readBytes(InputStream stream) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int count;
while ((count = stream.read(buffer)) != -1) {
baos.write(buffer, 0, count);
}
stream.close();
return baos.toByteArray();
} }
public static String readFromStream(InputStream is) throws Exception { public static String readFromStream(InputStream is) throws Exception {
@ -234,27 +187,6 @@ public final class FileUtil {
return sb.toString(); return sb.toString();
} }
public static String read(File file) throws Exception {
FileInputStream fin = new FileInputStream(file);
String ret = readFromStream(fin);
fin.close();
return ret;
}
public static boolean isExternalMemoryAvailable() {
Boolean isSDPresent = Environment.getExternalStorageState()
.equals(android.os.Environment.MEDIA_MOUNTED);
Boolean isSDSupportedDevice = Environment.isExternalStorageRemovable();
if (isSDSupportedDevice && isSDPresent) {
// yes SD-card is present
return true;
} else {
return false;
// Sorry
}
}
public static File safeGetCanonicalFile(File file) { public static File safeGetCanonicalFile(File file) {
try { try {
return file.getCanonicalFile(); return file.getCanonicalFile();
@ -264,5 +196,70 @@ public final class FileUtil {
} }
} }
public static String safeGetCanonicalPath(File file) {
try {
return file.getCanonicalPath();
} catch (IOException e) {
e.printStackTrace();
return file.getAbsolutePath();
}
}
public static String stripExtension(String str) {
if (str == null) {
return null;
}
int pos = str.lastIndexOf('.');
if (pos == -1) {
return str;
}
return str.substring(0, pos);
}
private FileUtil() {
}
private static void internalListFilesDeep(@NonNull Collection<File> files,
@NonNull File directory, @Nullable FileFilter fileFilter) {
File[] found = directory.listFiles(fileFilter);
if (found != null) {
for (File file : found) {
if (file.isDirectory()) {
internalListFilesDeep(files, file, fileFilter);
} else {
files.add(file);
}
}
}
}
private static String makePlaceholders(int len) {
StringBuilder sb = new StringBuilder(len * 2 - 1);
sb.append("?");
for (int i = 1; i < len; i++) {
sb.append(",?");
}
return sb.toString();
}
@Nullable
private static String[] toPathArray(@Nullable List<File> files) {
if (files != null) {
String[] paths = new String[files.size()];
for (int i = 0; i < files.size(); i++) {
/*try {
paths[i] = files.get(i).getCanonicalPath(); // canonical path is important here because we want to compare the path with the media store entry later
} catch (IOException e) {
e.printStackTrace();
paths[i] = files.get(i).getPath();
}*/
paths[i] = safeGetCanonicalPath(files.get(i));
}
return paths;
}
return null;
}
} }

View file

@ -1,9 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?><!--
<shape xmlns:android="http://schemas.android.com/apk/res/android" ~ Copyright (c) 2020 Hemanth Savarala.
android:shape="oval"> ~
<corners android:radius="35dp"/> ~ Licensed under the GNU General Public License v3
<stroke ~
android:color="@color/md_white_1000" ~ This is free software: you can redistribute it and/or modify it under
android:width="2dp"/> ~ 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="4dp" />
<stroke
android:width="2dp"
android:color="?attr/colorAccent" />
</shape> </shape>

View file

@ -4,6 +4,7 @@
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?attr/colorSurface"
android:clickable="true" android:clickable="true"
android:focusable="true"> android:focusable="true">
@ -18,10 +19,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:background="@drawable/shadow_up_full_theme" /> android:background="@drawable/shadow_up_full_theme" />
<View
android:id="@+id/mask"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -5,20 +5,16 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:clickable="true" android:clickable="true"
android:background="?attr/colorSurface"
android:focusable="true"> android:focusable="true">
<androidx.appcompat.widget.AppCompatImageView <androidx.appcompat.widget.AppCompatImageView
android:id="@+id/colorBackground" 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:background="?attr/colorSurface"
android:scaleType="centerCrop" /> android:scaleType="centerCrop" />
<View
android:id="@+id/mask"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#20000000" />
<include layout="@layout/shadow_statusbar_toolbar" /> <include layout="@layout/shadow_statusbar_toolbar" />
@ -86,5 +82,4 @@
tools:layout="@layout/fragment_card_blur_player_playback_controls" /> tools:layout="@layout/fragment_card_blur_player_playback_controls" />
</FrameLayout> </FrameLayout>
</FrameLayout> </FrameLayout>
</FrameLayout> </FrameLayout>

View file

@ -25,10 +25,25 @@
android:id="@+id/image" android:id="@+id/image"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toTopOf="@id/proText"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/title" app:layout_constraintTop_toBottomOf="@+id/title"
tools:src="@tools:sample/backgrounds/scenic" /> tools:src="@tools:sample/backgrounds/scenic" />
<com.google.android.material.textview.MaterialTextView
android:id="@+id/proText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/line_button"
android:paddingStart="16dp"
android:paddingTop="8dp"
android:paddingEnd="16dp"
android:paddingBottom="8dp"
android:text="@string/pro"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -826,4 +826,5 @@
<string name="drive_mode">Drive mode</string> <string name="drive_mode">Drive mode</string>
<string name="retro_music_player">Retro Music Player</string> <string name="retro_music_player">Retro Music Player</string>
<string name="sort_num_songs">Number of songs</string> <string name="sort_num_songs">Number of songs</string>
<string name="pro">Pro</string>
</resources> </resources>

View file

@ -7,6 +7,7 @@
<code.name.monkey.retromusic.preferences.BlacklistPreference <code.name.monkey.retromusic.preferences.BlacklistPreference
android:key="blacklist" android:key="blacklist"
app:enabled="false"
android:layout="@layout/list_item_view" android:layout="@layout/list_item_view"
android:summary="@string/pref_summary_blacklist" android:summary="@string/pref_summary_blacklist"
android:title="@string/pref_title_blacklist" android:title="@string/pref_title_blacklist"

View file

@ -54,12 +54,5 @@
android:summary="@string/pref_summary_colored_app_shortcuts" android:summary="@string/pref_summary_colored_app_shortcuts"
android:title="@string/pref_title_app_shortcuts" /> android:title="@string/pref_title_app_shortcuts" />
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference
android:defaultValue="false"
android:key="dominant_color"
android:layout="@layout/list_item_view_switch"
android:summary="@string/pref_summary_dominant_color"
android:title="@string/pref_title_toggle_dominant_color" />
</code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory> </code.name.monkey.appthemehelper.common.prefs.supportv7.ATEPreferenceCategory>
</androidx.preference.PreferenceScreen> </androidx.preference.PreferenceScreen>