Merge pull request #1456 from RetroMusicPlayer/dev-alpha

Release 6.0.4
This commit is contained in:
Daksh P. Jain 2023-03-13 18:52:02 +05:30 committed by GitHub
commit 74b317e159
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
116 changed files with 1069 additions and 647 deletions

View file

@ -1,11 +1,11 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: "androidx.navigation.safeargs.kotlin"
apply plugin: 'kotlin-parcelize'
apply plugin: 'com.google.devtools.ksp'
android {
compileSdk 32
compileSdk 33
namespace "code.name.monkey.retromusic"
defaultConfig {
@ -15,8 +15,8 @@ android {
vectorDrawables.useSupportLibrary = true
applicationId namespace
versionCode 10597
versionName '6.0.2-beta'
versionCode 10600
versionName '6.0.4'
buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"")
}
@ -45,7 +45,7 @@ android {
versionNameSuffix ' DEBUG'
}
}
flavorDimensions "version"
flavorDimensions = ["version"]
productFlavors {
normal {
dimension "version"
@ -78,7 +78,7 @@ android {
includeInApk = false
includeInBundle = false
}
configurations.all {
configurations.configureEach {
resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
}
}
@ -103,16 +103,16 @@ dependencies {
implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "androidx.appcompat:appcompat:$appcompat_version"
implementation 'androidx.annotation:annotation:1.4.0'
implementation 'androidx.annotation:annotation:1.6.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.recyclerview:recyclerview:1.3.0'
implementation "androidx.preference:preference-ktx:$preference_version"
implementation "androidx.core:core-ktx:$core_version"
implementation 'androidx.palette:palette-ktx:1.0.0'
implementation 'androidx.mediarouter:mediarouter:1.3.1'
//Cast Dependencies
normalImplementation 'com.google.android.gms:play-services-cast-framework:21.1.0'
normalImplementation 'com.google.android.gms:play-services-cast-framework:21.2.0'
//WebServer by NanoHttpd
normalImplementation "org.nanohttpd:nanohttpd:2.3.1"
@ -120,10 +120,10 @@ dependencies {
implementation "androidx.navigation:navigation-fragment-ktx:$navigation_version"
implementation "androidx.navigation:navigation-ui-ktx:$navigation_version"
def room_version = '2.5.0-alpha02'
def room_version = '2.5.0'
implementation "androidx.room:room-runtime:$room_version"
implementation "androidx.room:room-ktx:$room_version"
kapt "androidx.room:room-compiler:$room_version"
ksp "androidx.room:room-compiler:$room_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
@ -131,8 +131,8 @@ dependencies {
implementation "androidx.core:core-splashscreen:1.0.0"
normalImplementation 'com.google.android.play:feature-delivery:2.0.0'
normalImplementation 'com.google.android.play:review:2.0.0'
normalImplementation 'com.google.android.play:feature-delivery:2.0.1'
normalImplementation 'com.google.android.play:review:2.0.1'
implementation "com.google.android.material:material:$mdc_version"
@ -150,13 +150,13 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
def koin_version = '3.2.0'
def koin_version = '3.3.3'
implementation "io.insert-koin:koin-core:$koin_version"
implementation "io.insert-koin:koin-android:$koin_version"
def glide_version = '4.13.2'
def glide_version = '4.15.0'
implementation "com.github.bumptech.glide:glide:$glide_version"
kapt "com.github.bumptech.glide:compiler:$glide_version"
ksp "com.github.bumptech.glide:ksp:$glide_version"
implementation "com.github.bumptech.glide:okhttp3-integration:$glide_version"
implementation 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:1.0.0'
@ -174,7 +174,7 @@ dependencies {
implementation 'com.r0adkll:slidableactivity:2.1.0'
implementation 'com.heinrichreimersoftware:material-intro:2.0.0'
implementation 'com.github.dhaval2404:imagepicker:2.1'
implementation 'me.zhanghai.android.fastscroll:library:1.1.8'
implementation 'me.zhanghai.android.fastscroll:library:1.2.0'
implementation 'cat.ereza:customactivityoncrash:2.4.0'
implementation 'me.tankery.lib:circularSeekBar:1.4.1'
}

View file

@ -62,6 +62,31 @@
</head>
<body>
<div>
<h3>Looking for maintainers/contributors</h3>
<p>
We are currently seeking maintainers/contributors to help us continue developing and
improving our project. If you want to contribute your skills and expertise, you can visit our Github
<a style="color: lightblue;" href="https://github.com/RetroMusicPlayer/RetroMusicPlayer">here</a>, pull requests are welcome.
The app heavily relies on Kotlin.
</p>
</div>
<div>
<h5>March 13, 2023</h5>
<h2>v6.0.4</h2>
<h3>What's New</h3>
<ul>
<li>Minor redesign in Playlist details screen</li>
<li>Updated translations</li>
</ul>
<h3>Fixed</h3>
<ul>
<li>Fixed file popup menu actions in Folders tab</li>
<li>Fixed playlist image loading</li>
<li>Fixed blurry album art in Android 13</li>
<li>Minor bug fixes and improvements</li>
</ul>
</div>
<div>
<h5>July 10, 2022</h5>
<h2>v6.0.3<span class="tag"><i>Beta</i></span></h2>

View file

@ -168,10 +168,10 @@ private val viewModules = module {
)
}
viewModel { (playlist: PlaylistWithSongs) ->
viewModel { (playlistId: Long) ->
PlaylistDetailsViewModel(
get(),
playlist
playlistId
)
}

View file

@ -26,8 +26,8 @@ import code.name.monkey.retromusic.db.toSongEntity
import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.drawAboveSystemBars
import code.name.monkey.retromusic.glide.BlurTransformation
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper.Callback
@ -36,6 +36,7 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.MusicUtil
import com.bumptech.glide.Glide
import com.google.android.material.slider.Slider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@ -64,7 +65,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
lastPlaybackControlsColor = accentColor()
binding.close.setOnClickListener {
onBackPressed()
onBackPressedDispatcher.onBackPressed()
}
binding.repeatButton.drawAboveSystemBars()
}
@ -185,6 +186,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
lastPlaybackControlsColor,
PorterDuff.Mode.SRC_IN
)
else -> binding.shuffleButton.setColorFilter(
lastDisabledPlaybackControlsColor,
PorterDuff.Mode.SRC_IN
@ -201,6 +203,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
PorterDuff.Mode.SRC_IN
)
}
MusicService.REPEAT_MODE_ALL -> {
binding.repeatButton.setImageResource(R.drawable.ic_repeat)
binding.repeatButton.setColorFilter(
@ -208,6 +211,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
PorterDuff.Mode.SRC_IN
)
}
MusicService.REPEAT_MODE_THIS -> {
binding.repeatButton.setImageResource(R.drawable.ic_repeat_one)
binding.repeatButton.setColorFilter(
@ -235,7 +239,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
binding.songTitle.text = song.title
binding.songText.text = song.artistName
GlideApp.with(this)
Glide.with(this)
.load(RetroGlideExtension.getSongModel(song))
.songCoverOptions(song)
.transform(BlurTransformation.Builder(this).build())

View file

@ -77,7 +77,7 @@ class LicenseActivity : AbsThemeActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
onBackPressedDispatcher.onBackPressed()
return true
}
return super.onOptionsItemSelected(item)

View file

@ -26,11 +26,13 @@ import code.name.monkey.retromusic.extensions.hideStatusBar
import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.player.lockscreen.LockScreenControlsFragment
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import com.r0adkll.slidr.Slidr
import com.r0adkll.slidr.model.SlidrConfig
import com.r0adkll.slidr.model.SlidrListener
@ -88,7 +90,7 @@ class LockScreenActivity : AbsMusicServiceActivity() {
} else {
window.addFlags(
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
// or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
// or WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
)
}
}
@ -105,7 +107,7 @@ class LockScreenActivity : AbsMusicServiceActivity() {
private fun updateSongs() {
val song = MusicPlayerRemote.currentSong
GlideApp.with(this)
Glide.with(this)
.asBitmapPalette()
.songCoverOptions(song)
.load(RetroGlideExtension.getSongModel(song))

View file

@ -22,6 +22,7 @@ import android.content.res.ColorStateList
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import androidx.activity.OnBackPressedCallback
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.net.toUri
@ -61,9 +62,11 @@ class PermissionActivity : AbsMusicServiceActivity() {
if (VersionUtils.hasS()) {
binding.bluetoothPermission.show()
binding.bluetoothPermission.setButtonClick {
ActivityCompat.requestPermissions(this,
ActivityCompat.requestPermissions(
this,
arrayOf(BLUETOOTH_CONNECT),
BLUETOOTH_PERMISSION_REQUEST)
BLUETOOTH_PERMISSION_REQUEST
)
}
} else {
binding.audioPermission.setNumber("2")
@ -81,14 +84,22 @@ class PermissionActivity : AbsMusicServiceActivity() {
finish()
}
}
onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
finishAffinity()
remove()
}
})
}
private fun setupTitle() {
val color = accentColor()
val hexColor = String.format("#%06X", 0xFFFFFF and color)
val appName =
getString(R.string.message_welcome,
"<b>Retro <span style='color:$hexColor';>Music</span></b>")
getString(
R.string.message_welcome,
"<b>Retro <span style='color:$hexColor';>Music</span></b>"
)
.parseAsHtml()
binding.appNameText.text = appName
}
@ -118,23 +129,22 @@ class PermissionActivity : AbsMusicServiceActivity() {
}
private fun hasStoragePermission(): Boolean {
return ActivityCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
return ActivityCompat.checkSelfPermission(
this,
Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED
}
@RequiresApi(Build.VERSION_CODES.S)
private fun hasBluetoothPermission(): Boolean {
return ActivityCompat.checkSelfPermission(this,
BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED
return ActivityCompat.checkSelfPermission(
this,
BLUETOOTH_CONNECT
) == PackageManager.PERMISSION_GRANTED
}
@RequiresApi(Build.VERSION_CODES.M)
private fun hasAudioPermission(): Boolean {
return Settings.System.canWrite(this)
}
override fun onBackPressed() {
super.onBackPressed()
finishAffinity()
}
}

View file

@ -22,20 +22,22 @@ import android.os.Bundle
import android.provider.MediaStore.Images.Media
import android.view.MenuItem
import androidx.core.net.toUri
import androidx.core.os.BundleCompat
import androidx.core.view.drawToBitmap
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
import code.name.monkey.retromusic.databinding.ActivityShareInstagramBinding
import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.setLightStatusBar
import code.name.monkey.retromusic.extensions.setStatusBarColor
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.Share
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
/**
* Created by hemanths on 2020-02-02.
@ -51,7 +53,7 @@ class ShareInstagramStory : AbsThemeActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
onBackPressedDispatcher.onBackPressed()
return true
}
return super.onOptionsItemSelected(item)
@ -66,16 +68,15 @@ class ShareInstagramStory : AbsThemeActivity() {
binding.toolbar.setBackgroundColor(Color.TRANSPARENT)
setSupportActionBar(binding.toolbar)
val song = intent.extras?.getParcelable<Song>(EXTRA_SONG)
val song = intent.extras?.let { BundleCompat.getParcelable(it, EXTRA_SONG, Song::class.java) }
song?.let { songFinal ->
GlideApp.with(this)
Glide.with(this)
.asBitmapPalette()
.songCoverOptions(songFinal)
.load(RetroGlideExtension.getSongModel(songFinal))
.into(object : RetroMusicColoredTarget(binding.image) {
override fun onColorReady(colors: MediaNotificationProcessor) {
val isColorLight = ColorUtil.isColorLight(colors.backgroundColor)
setColors(isColorLight, colors.backgroundColor)
setColors(colors.backgroundColor)
}
})
@ -103,22 +104,7 @@ class ShareInstagramStory : AbsThemeActivity() {
ColorStateList.valueOf(accentColor())
}
private fun setColors(colorLight: Boolean, color: Int) {
setLightStatusBar(colorLight)
binding.toolbar.setTitleTextColor(
MaterialValueHelper.getPrimaryTextColor(
this@ShareInstagramStory,
colorLight
)
)
binding.toolbar.navigationIcon?.setTintList(
ColorStateList.valueOf(
MaterialValueHelper.getPrimaryTextColor(
this@ShareInstagramStory,
colorLight
)
)
)
private fun setColors(color: Int) {
binding.mainContent.background =
GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,

View file

@ -30,7 +30,7 @@ class SupportDevelopmentActivity : AbsThemeActivity() {
lateinit var binding: ActivityDonationBinding
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
onBackPressedDispatcher.onBackPressed()
return true
}
return super.onOptionsItemSelected(item)

View file

@ -1,12 +1,17 @@
package code.name.monkey.retromusic.activities
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Color
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.core.content.PackageManagerCompat
import androidx.core.content.pm.PackageInfoCompat
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.FragmentActivity
@ -22,7 +27,7 @@ import code.name.monkey.retromusic.extensions.openUrl
import code.name.monkey.retromusic.util.PreferenceUtil.lastVersion
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import java.nio.charset.StandardCharsets
import java.util.*
import java.util.Locale
class WhatsNewFragment : BottomSheetDialogFragment() {
private var _binding: FragmentWhatsNewBinding? = null
@ -41,7 +46,7 @@ class WhatsNewFragment : BottomSheetDialogFragment() {
super.onViewCreated(view, savedInstanceState)
try {
val buf = StringBuilder()
val stream= requireContext().assets.open("retro-changelog.html")
val stream = requireContext().assets.open("retro-changelog.html")
stream.reader(StandardCharsets.UTF_8).buffered().use { br ->
var str: String?
while (br.readLine().also { str = it } != null) {
@ -76,6 +81,17 @@ class WhatsNewFragment : BottomSheetDialogFragment() {
)
)
binding.webView.loadData(changeLog, "text/html", "UTF-8")
binding.webView.webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(
view: WebView?,
request: WebResourceRequest?
): Boolean {
val url = request?.url ?: return false
//you can do checks here e.g. url.host equals to target one
startActivity(Intent(Intent.ACTION_VIEW, url))
return true
}
}
} catch (e: Throwable) {
binding.webView.loadData(
"<h1>Unable to load</h1><p>" + e.localizedMessage + "</p>", "text/html", "UTF-8"

View file

@ -26,6 +26,7 @@ import android.view.ViewGroup
import android.view.ViewTreeObserver
import android.view.animation.PathInterpolator
import android.widget.FrameLayout
import androidx.activity.OnBackPressedCallback
import androidx.core.animation.doOnEnd
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.isGone
@ -33,10 +34,44 @@ import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
import androidx.fragment.app.commit
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.ADAPTIVE_COLOR_APP
import code.name.monkey.retromusic.ALBUM_COVER_STYLE
import code.name.monkey.retromusic.ALBUM_COVER_TRANSFORM
import code.name.monkey.retromusic.CAROUSEL_EFFECT
import code.name.monkey.retromusic.CIRCLE_PLAY_BUTTON
import code.name.monkey.retromusic.EXTRA_SONG_INFO
import code.name.monkey.retromusic.KEEP_SCREEN_ON
import code.name.monkey.retromusic.LIBRARY_CATEGORIES
import code.name.monkey.retromusic.NOW_PLAYING_SCREEN_ID
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.SCREEN_ON_LYRICS
import code.name.monkey.retromusic.SWIPE_ANYWHERE_NOW_PLAYING
import code.name.monkey.retromusic.SWIPE_DOWN_DISMISS
import code.name.monkey.retromusic.TAB_TEXT_MODE
import code.name.monkey.retromusic.TOGGLE_ADD_CONTROLS
import code.name.monkey.retromusic.TOGGLE_FULL_SCREEN
import code.name.monkey.retromusic.TOGGLE_VOLUME
import code.name.monkey.retromusic.activities.PermissionActivity
import code.name.monkey.retromusic.databinding.SlidingMusicPanelLayoutBinding
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.currentFragment
import code.name.monkey.retromusic.extensions.darkAccentColor
import code.name.monkey.retromusic.extensions.dip
import code.name.monkey.retromusic.extensions.getBottomInsets
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.isColorLight
import code.name.monkey.retromusic.extensions.isLandscape
import code.name.monkey.retromusic.extensions.keepScreenOn
import code.name.monkey.retromusic.extensions.maybeSetScreenOn
import code.name.monkey.retromusic.extensions.peekHeightAnimate
import code.name.monkey.retromusic.extensions.setLightNavigationBar
import code.name.monkey.retromusic.extensions.setLightNavigationBarAuto
import code.name.monkey.retromusic.extensions.setLightStatusBar
import code.name.monkey.retromusic.extensions.setLightStatusBarAuto
import code.name.monkey.retromusic.extensions.setNavigationBarColorPreOreo
import code.name.monkey.retromusic.extensions.setTaskDescriptionColor
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.NowPlayingScreen
import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
@ -68,7 +103,13 @@ import code.name.monkey.retromusic.util.ViewUtil
import code.name.monkey.retromusic.util.logD
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetBehavior.*
import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_DRAGGING
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_SETTLING
import com.google.android.material.bottomsheet.BottomSheetBehavior.from
import org.koin.androidx.viewmodel.ext.android.viewModel
@ -120,21 +161,25 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
keepScreenOn(true)
}
}
STATE_COLLAPSED -> {
onPanelCollapsed()
if ((PreferenceUtil.lyricsScreenOn && PreferenceUtil.showLyrics) || !PreferenceUtil.isScreenOnEnabled) {
keepScreenOn(false)
}
}
STATE_SETTLING, STATE_DRAGGING -> {
if (fromNotification) {
binding.navigationView.bringToFront()
fromNotification = false
}
}
STATE_HIDDEN -> {
MusicPlayerRemote.clearQueue()
}
else -> {
logD("Do a flip")
}
@ -173,6 +218,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
bottomSheetBehavior = from(binding.slidingPanel)
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallbackList)
bottomSheetBehavior.isHideable = PreferenceUtil.swipeDownToDismiss
bottomSheetBehavior.significantVelocityThreshold = 300
setMiniPlayerAlphaProgress(0F)
}
@ -185,6 +231,14 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
if (bottomSheetBehavior.state == STATE_EXPANDED) {
setMiniPlayerAlphaProgress(1f)
}
onBackPressedDispatcher.addCallback(object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
if (!handleBackPress()) {
remove()
onBackPressedDispatcher.onBackPressed()
}
}
})
}
override fun onDestroy() {
@ -198,9 +252,11 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
SWIPE_DOWN_DISMISS -> {
bottomSheetBehavior.isHideable = PreferenceUtil.swipeDownToDismiss
}
TOGGLE_ADD_CONTROLS -> {
miniPlayerFragment?.setUpButtons()
}
NOW_PLAYING_SCREEN_ID -> {
chooseFragmentForTheme()
binding.slidingPanel.updateLayoutParams<ViewGroup.LayoutParams> {
@ -212,33 +268,41 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
onServiceConnected()
}
}
ALBUM_COVER_TRANSFORM, CAROUSEL_EFFECT,
ALBUM_COVER_STYLE, TOGGLE_VOLUME, EXTRA_SONG_INFO, CIRCLE_PLAY_BUTTON,
-> {
chooseFragmentForTheme()
onServiceConnected()
}
SWIPE_ANYWHERE_NOW_PLAYING -> {
playerFragment.addSwipeDetector()
}
ADAPTIVE_COLOR_APP -> {
if (PreferenceUtil.nowPlayingScreen in listOf(Normal, Material, Flat)) {
chooseFragmentForTheme()
onServiceConnected()
}
}
LIBRARY_CATEGORIES -> {
updateTabs()
}
TAB_TEXT_MODE -> {
navigationView.labelVisibilityMode = PreferenceUtil.tabTitleMode
}
TOGGLE_FULL_SCREEN -> {
recreate()
}
SCREEN_ON_LYRICS -> {
keepScreenOn(bottomSheetBehavior.state == STATE_EXPANDED && PreferenceUtil.lyricsScreenOn && PreferenceUtil.showLyrics || PreferenceUtil.isScreenOnEnabled)
}
KEEP_SCREEN_ON -> {
maybeSetScreenOn()
}
@ -338,10 +402,6 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
}
}
override fun onBackPressed() {
if (!handleBackPress()) super.onBackPressed()
}
private fun handleBackPress(): Boolean {
if (bottomSheetBehavior.peekHeight != 0 && playerFragment.onBackPressed()) return true
if (panelState == STATE_EXPANDED) {
@ -446,14 +506,14 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
hideBottomSheet(
hide = hideBottomSheet,
animate = animate,
isBottomNavVisible = visible && navigationView is BottomNavigationView
isBottomNavVisible = visible && navigationView is BottomNavigationView
)
}
fun hideBottomSheet(
hide: Boolean,
animate: Boolean = false,
isBottomNavVisible: Boolean = navigationView.isVisible && navigationView is BottomNavigationView,
isBottomNavVisible: Boolean = navigationView.isVisible && navigationView is BottomNavigationView,
) {
val heightOfBar = windowInsets.getBottomInsets() + dip(R.dimen.mini_player_height)
val heightOfBarWithTabs = heightOfBar + dip(R.dimen.bottom_nav_height)
@ -475,8 +535,10 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity(),
} else {
bottomSheetBehavior.peekHeight = heightOfBarWithTabs
}
libraryViewModel.setFabMargin(this,
dip(R.dimen.bottom_nav_mini_player_height))
libraryViewModel.setFabMargin(
this,
dip(R.dimen.bottom_nav_mini_player_height)
)
} else {
logD("Details")
if (animate) {

View file

@ -79,7 +79,7 @@ open class BugReportActivity : AbsThemeActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
if (item.itemId == android.R.id.home) {
onBackPressed()
onBackPressedDispatcher.onBackPressed()
}
return super.onOptionsItemSelected(item)
}

View file

@ -56,7 +56,7 @@ import org.jaudiotagger.audio.AudioFileIO
import org.jaudiotagger.tag.FieldKey
import org.koin.android.ext.android.inject
import java.io.File
import java.util.*
import java.util.Collections
abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
abstract val editorImage: ImageView
@ -307,7 +307,7 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
super.onBackPressed()
onBackPressedDispatcher.onBackPressed()
return true
}
}
@ -409,15 +409,18 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
loadImageFromFile(it)
}
}
SAFGuideActivity.REQUEST_CODE_SAF_GUIDE -> {
SAFUtil.openTreePicker(this)
}
SAFUtil.REQUEST_SAF_PICK_TREE -> {
if (resultCode == Activity.RESULT_OK) {
SAFUtil.saveTreeUri(this, intent)
writeTags(savedSongPaths)
}
}
SAFUtil.REQUEST_SAF_PICK_FILE -> {
if (resultCode == Activity.RESULT_OK) {
writeTags(Collections.singletonList(currentSongPath + SAFUtil.SEPARATOR + intent!!.dataString))

View file

@ -30,8 +30,12 @@ import androidx.core.widget.doAfterTextChanged
import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.databinding.ActivityAlbumTagEditorBinding
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.extensions.appHandleColor
import code.name.monkey.retromusic.extensions.defaultFooterColor
import code.name.monkey.retromusic.extensions.isColorLight
import code.name.monkey.retromusic.extensions.setTint
import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.model.ArtworkInfo
import code.name.monkey.retromusic.model.Song
@ -40,12 +44,13 @@ import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RetroColorUtil.generatePalette
import code.name.monkey.retromusic.util.RetroColorUtil.getColor
import code.name.monkey.retromusic.util.logD
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.target.ImageViewTarget
import com.bumptech.glide.request.transition.Transition
import com.google.android.material.shape.MaterialShapeDrawable
import org.jaudiotagger.tag.FieldKey
import java.util.*
import java.util.EnumMap
class AlbumTagEditorActivity : AbsTagEditorActivity<ActivityAlbumTagEditorBinding>() {
@ -132,7 +137,9 @@ class AlbumTagEditorActivity : AbsTagEditorActivity<ActivityAlbumTagEditorBindin
}
override fun loadImageFromFile(selectedFile: Uri?) {
GlideApp.with(this@AlbumTagEditorActivity).asBitmapPalette().load(selectedFile)
Glide.with(this@AlbumTagEditorActivity)
.asBitmapPalette()
.load(selectedFile)
.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)
.into(object : ImageViewTarget<BitmapPaletteWrapper>(binding.editorImage) {
override fun onResourceReady(

View file

@ -31,7 +31,7 @@ import code.name.monkey.appthemehelper.util.MaterialValueHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.databinding.ActivitySongTagEditorBinding
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.model.ArtworkInfo
import code.name.monkey.retromusic.repository.SongRepository
@ -39,6 +39,7 @@ import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RetroColorUtil
import code.name.monkey.retromusic.util.logD
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.request.target.ImageViewTarget
import com.bumptech.glide.request.transition.Transition
@ -171,8 +172,11 @@ class SongTagEditorActivity : AbsTagEditorActivity<ActivitySongTagEditorBinding>
override fun getSongUris(): List<Uri> = listOf(MusicUtil.getSongFileUri(id))
override fun loadImageFromFile(selectedFile: Uri?) {
GlideApp.with(this@SongTagEditorActivity).asBitmapPalette().load(selectedFile)
.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)
Glide.with(this@SongTagEditorActivity)
.asBitmapPalette()
.load(selectedFile)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(object : ImageViewTarget<BitmapPaletteWrapper>(binding.editorImage) {
override fun onResourceReady(
resource: BitmapPaletteWrapper,

View file

@ -23,13 +23,15 @@ import androidx.fragment.app.FragmentActivity
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.databinding.ItemGenreBinding
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.interfaces.IGenreClickListener
import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import java.util.*
/**
@ -68,10 +70,10 @@ class GenreAdapter(
private fun loadGenreImage(genre: Genre, holder: GenreAdapter.ViewHolder) {
val genreSong = MusicUtil.songByGenre(genre.id)
GlideApp.with(activity)
Glide.with(activity)
.asBitmapPalette()
.load(RetroGlideExtension.getSongModel(genreSong))
.songCoverOptions(genreSong)
.load(RetroGlideExtension.getSongModel(genreSong))
.into(object : RetroMusicColoredTarget(holder.binding.image) {
override fun onColorReady(colors: MediaNotificationProcessor) {
setColors(holder, colors)

View file

@ -29,8 +29,10 @@ import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.albumCoverOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.artistImageOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.menu.SongMenuHelper
import code.name.monkey.retromusic.model.Album
@ -38,6 +40,7 @@ import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.model.Genre
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil
import com.bumptech.glide.Glide
import java.util.*
class SearchAdapter(
@ -68,6 +71,7 @@ class SearchAdapter(
false
), viewType
)
ALBUM, ARTIST, ALBUM_ARTIST -> ViewHolder(
LayoutInflater.from(activity).inflate(
R.layout.item_list_big,
@ -75,6 +79,7 @@ class SearchAdapter(
false
), viewType
)
else -> ViewHolder(
LayoutInflater.from(activity).inflate(R.layout.item_list, parent, false),
viewType
@ -89,24 +94,30 @@ class SearchAdapter(
val album = dataSet[position] as Album
holder.title?.text = album.title
holder.text?.text = album.artistName
GlideApp.with(activity).asDrawable().albumCoverOptions(album.safeGetFirstSong()).load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
Glide.with(activity).asDrawable().albumCoverOptions(album.safeGetFirstSong())
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.into(holder.image!!)
}
ARTIST -> {
holder.imageTextContainer?.isVisible = true
val artist = dataSet[position] as Artist
holder.title?.text = artist.name
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
GlideApp.with(activity).asDrawable().artistImageOptions(artist).load(
RetroGlideExtension.getArtistModel(artist)).into(holder.image!!)
Glide.with(activity).asDrawable().artistImageOptions(artist).load(
RetroGlideExtension.getArtistModel(artist)
).into(holder.image!!)
}
SONG -> {
holder.imageTextContainer?.isVisible = true
val song = dataSet[position] as Song
holder.title?.text = song.title
holder.text?.text = song.albumName
GlideApp.with(activity).asDrawable().songCoverOptions(song).load(RetroGlideExtension.getSongModel(song)).into(holder.image!!)
Glide.with(activity).asDrawable().songCoverOptions(song)
.load(RetroGlideExtension.getSongModel(song)).into(holder.image!!)
}
GENRE -> {
val genre = dataSet[position] as Genre
holder.title?.text = genre.name
@ -119,19 +130,23 @@ class SearchAdapter(
)
)
}
PLAYLIST -> {
val playlist = dataSet[position] as PlaylistWithSongs
holder.title?.text = playlist.playlistEntity.playlistName
//holder.text?.text = MusicUtil.playlistInfoString(activity, playlist.songs)
}
ALBUM_ARTIST -> {
holder.imageTextContainer?.isVisible = true
val artist = dataSet[position] as Artist
holder.title?.text = artist.name
holder.text?.text = MusicUtil.getArtistInfoString(activity, artist)
GlideApp.with(activity).asDrawable().artistImageOptions(artist).load(
RetroGlideExtension.getArtistModel(artist)).into(holder.image!!)
Glide.with(activity).asDrawable().artistImageOptions(artist).load(
RetroGlideExtension.getArtistModel(artist)
).into(holder.image!!)
}
else -> {
holder.title?.text = dataSet[position].toString()
holder.title?.setTextColor(ThemeStore.accentColor(activity))
@ -177,30 +192,35 @@ class SearchAdapter(
bundleOf(EXTRA_ALBUM_ID to (item as Album).id)
)
}
ARTIST -> {
activity.findNavController(R.id.fragment_container).navigate(
R.id.artistDetailsFragment,
bundleOf(EXTRA_ARTIST_ID to (item as Artist).id)
)
}
ALBUM_ARTIST ->{
ALBUM_ARTIST -> {
activity.findNavController(R.id.fragment_container).navigate(
R.id.albumArtistDetailsFragment,
bundleOf(EXTRA_ARTIST_NAME to (item as Artist).name)
)
}
GENRE -> {
activity.findNavController(R.id.fragment_container).navigate(
R.id.genreDetailsFragment,
bundleOf(EXTRA_GENRE to (item as Genre))
)
}
PLAYLIST -> {
activity.findNavController(R.id.fragment_container).navigate(
R.id.playlistDetailsFragment,
bundleOf(EXTRA_PLAYLIST to (item as PlaylistWithSongs))
bundleOf(EXTRA_PLAYLIST_ID to (item as PlaylistWithSongs).playlistEntity.playListId)
)
}
SONG -> {
MusicPlayerRemote.playNext(item as Song)
MusicPlayerRemote.playNextSong()

View file

@ -26,11 +26,11 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.extensions.getTintedDrawable
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.audiocover.AudioFileCover
import code.name.monkey.retromusic.interfaces.ICallbacks
import code.name.monkey.retromusic.util.MusicUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.signature.MediaStoreSignature
import me.zhanghai.android.fastscroll.PopupTextProvider
@ -109,7 +109,7 @@ class SongFileAdapter(
)
} else {
val error = activity.getTintedDrawable(R.drawable.ic_audio_file, iconColor)
GlideApp.with(activity)
Glide.with(activity)
.load(AudioFileCover(file.path))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.error(error)

View file

@ -24,8 +24,9 @@ import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.albumCoverOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
@ -35,6 +36,7 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import me.zhanghai.android.fastscroll.PopupTextProvider
open class AlbumAdapter(
@ -110,7 +112,9 @@ open class AlbumAdapter(
return
}
val song = album.safeGetFirstSong()
GlideApp.with(activity).asBitmapPalette().albumCoverOptions(song)
Glide.with(activity)
.asBitmapPalette()
.albumCoverOptions(song)
//.checkIgnoreMediaStore()
.load(RetroGlideExtension.getSongModel(song))
.into(object : RetroMusicColoredTarget(holder.image!!) {
@ -160,6 +164,7 @@ open class AlbumAdapter(
when (PreferenceUtil.albumSortOrder) {
SortOrder.AlbumSortOrder.ALBUM_A_Z, SortOrder.AlbumSortOrder.ALBUM_Z_A -> sectionName =
dataSet[position].title
SortOrder.AlbumSortOrder.ALBUM_ARTIST -> sectionName = dataSet[position].albumArtist
SortOrder.AlbumSortOrder.ALBUM_YEAR -> return MusicUtil.getYearString(
dataSet[position].year

View file

@ -19,6 +19,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.core.os.BundleCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
@ -26,16 +27,24 @@ import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.fragments.AlbumCoverStyle
import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
import code.name.monkey.retromusic.fragments.NowPlayingScreen.Card
import code.name.monkey.retromusic.fragments.NowPlayingScreen.Classic
import code.name.monkey.retromusic.fragments.NowPlayingScreen.Fit
import code.name.monkey.retromusic.fragments.NowPlayingScreen.Full
import code.name.monkey.retromusic.fragments.NowPlayingScreen.Gradient
import code.name.monkey.retromusic.fragments.NowPlayingScreen.Peek
import code.name.monkey.retromusic.fragments.NowPlayingScreen.Tiny
import code.name.monkey.retromusic.fragments.base.goToLyrics
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.misc.CustomFragmentStatePagerAdapter
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_EXPANDED
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.Dispatchers
@ -95,7 +104,7 @@ class AlbumCoverPagerAdapter(
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (arguments != null) {
song = requireArguments().getParcelable(SONG_ARG)!!
song = BundleCompat.getParcelable(requireArguments(), SONG_ARG, Song::class.java)!!
}
}
@ -164,7 +173,9 @@ class AlbumCoverPagerAdapter(
}
private fun loadAlbumCover(albumCover: ImageView) {
GlideApp.with(this).asBitmapPalette().songCoverOptions(song)
Glide.with(this)
.asBitmapPalette()
.songCoverOptions(song)
//.checkIgnoreMediaStore()
.load(RetroGlideExtension.getSongModel(song))
.dontAnimate()

View file

@ -17,14 +17,16 @@ package code.name.monkey.retromusic.adapter.album
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.albumCoverOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.HorizontalAdapterHelper
import code.name.monkey.retromusic.interfaces.IAlbumClickListener
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
class HorizontalAlbumAdapter(
activity: FragmentActivity,
@ -47,7 +49,9 @@ class HorizontalAlbumAdapter(
override fun loadAlbumCover(album: Album, holder: ViewHolder) {
if (holder.image == null) return
GlideApp.with(activity).asBitmapPalette().albumCoverOptions(album.safeGetFirstSong())
Glide.with(activity)
.asBitmapPalette()
.albumCoverOptions(album.safeGetFirstSong())
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
.into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(colors: MediaNotificationProcessor) {

View file

@ -27,8 +27,9 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.artistImageOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.IAlbumArtistClickListener
@ -38,6 +39,7 @@ import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import me.zhanghai.android.fastscroll.PopupTextProvider
class ArtistAdapter(
@ -109,10 +111,10 @@ class ArtistAdapter(
if (holder.image == null) {
return
}
GlideApp.with(activity)
Glide.with(activity)
.asBitmapPalette()
.load(RetroGlideExtension.getArtistModel(artist))
.artistImageOptions(artist)
.load(RetroGlideExtension.getArtistModel(artist))
.transition(RetroGlideExtension.getDefaultTransition())
.into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(colors: MediaNotificationProcessor) {

View file

@ -33,7 +33,7 @@ import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.toSongs
import code.name.monkey.retromusic.extensions.dipToPix
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension.playlistOptions
import code.name.monkey.retromusic.glide.playlistPreview.PlaylistPreview
import code.name.monkey.retromusic.helper.SortOrder.PlaylistSortOrder
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
@ -42,6 +42,7 @@ import code.name.monkey.retromusic.interfaces.IPlaylistClickListener
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import me.zhanghai.android.fastscroll.PopupTextProvider
class PlaylistAdapter(
@ -105,10 +106,8 @@ class PlaylistAdapter(
holder.image?.setPadding(activity.dipToPix(8F).toInt())
holder.image?.setImageDrawable(getIconRes())
} else {
GlideApp.with(activity)
.load(
PlaylistPreview(playlist)
)
Glide.with(activity)
.load(PlaylistPreview(playlist))
.playlistOptions()
.into(holder.image!!)
}

View file

@ -24,12 +24,8 @@ import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.db.toSongEntity
import code.name.monkey.retromusic.db.toSongsEntity
import code.name.monkey.retromusic.dialogs.RemoveSongFromPlaylistDialog
import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.accentOutlineColor
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import com.google.android.material.button.MaterialButton
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
import kotlinx.coroutines.Dispatchers
@ -37,11 +33,11 @@ import kotlinx.coroutines.launch
import org.koin.androidx.viewmodel.ext.android.viewModel
class OrderablePlaylistSongAdapter(
private val playlist: PlaylistEntity,
private val playlistId: Long,
activity: FragmentActivity,
dataSet: MutableList<Song>,
itemLayoutRes: Int,
) : AbsOffsetSongAdapter(activity, dataSet, itemLayoutRes),
) : SongAdapter(activity, dataSet, itemLayoutRes),
DraggableItemAdapter<OrderablePlaylistSongAdapter.ViewHolder> {
val libraryViewModel: LibraryViewModel by activity.viewModel()
@ -65,45 +61,20 @@ class OrderablePlaylistSongAdapter(
return ViewHolder(view)
}
override fun getItemViewType(position: Int): Int {
return if (position == 0) OFFSET_ITEM else SONG
}
override fun onBindViewHolder(holder: SongAdapter.ViewHolder, position: Int) {
if (holder.itemViewType == OFFSET_ITEM) {
val viewHolder = holder as ViewHolder
viewHolder.playAction?.let {
it.setOnClickListener {
MusicPlayerRemote.openQueue(dataSet, 0, true)
}
it.accentOutlineColor()
}
viewHolder.shuffleAction?.let {
it.setOnClickListener {
MusicPlayerRemote.openAndShuffleQueue(dataSet, true)
}
it.accentColor()
}
} else {
super.onBindViewHolder(holder, position - 1)
}
}
override fun onMultipleItemAction(menuItem: MenuItem, selection: List<Song>) {
when (menuItem.itemId) {
R.id.action_remove_from_playlist -> RemoveSongFromPlaylistDialog.create(
selection.toSongsEntity(
playlist
playlistId
)
)
.show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
else -> super.onMultipleItemAction(menuItem, selection)
}
}
inner class ViewHolder(itemView: View) : AbsOffsetSongAdapter.ViewHolder(itemView) {
val playAction: MaterialButton? = itemView.findViewById(R.id.playAction)
val shuffleAction: MaterialButton? = itemView.findViewById(R.id.shuffleAction)
inner class ViewHolder(itemView: View) : SongAdapter.ViewHolder(itemView) {
override var songMenuRes: Int
get() = R.menu.menu_item_playlist_song
@ -114,7 +85,7 @@ class OrderablePlaylistSongAdapter(
override fun onSongMenuItemClick(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_remove_from_playlist -> {
RemoveSongFromPlaylistDialog.create(song.toSongEntity(playlist.playListId))
RemoveSongFromPlaylistDialog.create(song.toSongEntity(playlistId))
.show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
return true
}
@ -147,7 +118,7 @@ class OrderablePlaylistSongAdapter(
}
override fun onGetItemDraggableRange(holder: ViewHolder, position: Int): ItemDraggableRange {
return ItemDraggableRange(1, itemCount - 1)
return ItemDraggableRange(0, itemCount - 1)
}
override fun onCheckCanDrop(draggingPosition: Int, dropPosition: Int): Boolean {

View file

@ -19,8 +19,8 @@ import android.view.View
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicPlayerRemote.isPlaying
import code.name.monkey.retromusic.helper.MusicPlayerRemote.playNextSong
@ -28,6 +28,7 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote.removeFromQueue
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.ViewUtil
import com.bumptech.glide.Glide
import com.h6ah4i.android.widget.advrecyclerview.draggable.DraggableItemAdapter
import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
@ -76,7 +77,7 @@ class PlayingQueueAdapter(
if (holder.image == null) {
return
}
GlideApp.with(activity)
Glide.with(activity)
.load(RetroGlideExtension.getSongModel(song))
.songCoverOptions(song)
.into(holder.image!!)
@ -195,7 +196,7 @@ class PlayingQueueAdapter(
return if (result == SwipeableItemConstants.RESULT_CANCELED) {
SwipeResultActionDefault()
} else {
SwipedResultActionRemoveItem(this, position, activity)
SwipedResultActionRemoveItem(this, position)
}
}
@ -216,12 +217,9 @@ class PlayingQueueAdapter(
internal class SwipedResultActionRemoveItem(
private val adapter: PlayingQueueAdapter,
private val position: Int,
private val activity: FragmentActivity,
) : SwipeResultActionRemoveItem() {
private var songToRemove: Song? = null
private val isPlaying: Boolean = MusicPlayerRemote.isPlaying
private val songProgressMillis = 0
override fun onPerformAction() {
// currentlyShownSnackbar = null
}

View file

@ -29,8 +29,9 @@ import code.name.monkey.retromusic.EXTRA_ALBUM_ID
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder
@ -41,6 +42,7 @@ import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import me.zhanghai.android.fastscroll.PopupTextProvider
/**
@ -116,7 +118,9 @@ open class SongAdapter(
if (holder.image == null) {
return
}
GlideApp.with(activity).asBitmapPalette().songCoverOptions(song)
Glide.with(activity)
.asBitmapPalette()
.songCoverOptions(song)
.load(RetroGlideExtension.getSongModel(song))
.into(object : RetroMusicColoredTarget(holder.image!!) {
override fun onColorReady(colors: MediaNotificationProcessor) {
@ -155,7 +159,11 @@ open class SongAdapter(
override fun getPopupText(position: Int): String {
val sectionName: String? = when (PreferenceUtil.songSortOrder) {
SortOrder.SongSortOrder.SONG_DEFAULT -> return MusicUtil.getSectionName(dataSet[position].title, true)
SortOrder.SongSortOrder.SONG_DEFAULT -> return MusicUtil.getSectionName(
dataSet[position].title,
true
)
SortOrder.SongSortOrder.SONG_A_Z, SortOrder.SongSortOrder.SONG_Z_A -> dataSet[position].title
SortOrder.SongSortOrder.SONG_ALBUM -> dataSet[position].albumName
SortOrder.SongSortOrder.SONG_ARTIST -> dataSet[position].artistName

View file

@ -29,7 +29,6 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.extensions.getTintedDrawable
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
@ -152,7 +151,7 @@ class AppWidgetBig : BaseAppWidget() {
if (target != null) {
Glide.with(service).clear(target)
}
target = GlideApp.with(appContext)
target = Glide.with(appContext)
.asBitmap()
//.checkIgnoreMediaStore()
.load(RetroGlideExtension.getSongModel(song))

View file

@ -29,8 +29,9 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.extensions.getTintedDrawable
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
@ -143,7 +144,9 @@ class AppWidgetCard : BaseAppWidget() {
if (target != null) {
Glide.with(service).clear(target)
}
target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
target = Glide.with(service)
.asBitmapPalette()
.songCoverOptions(song)
.load(RetroGlideExtension.getSongModel(song))
.centerCrop()
.into(object : CustomTarget<BitmapPaletteWrapper>(imageSize, imageSize) {

View file

@ -28,8 +28,9 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.extensions.getTintedDrawable
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_PAUSE
@ -114,7 +115,9 @@ class AppWidgetCircle : BaseAppWidget() {
if (target != null) {
Glide.with(service).clear(target)
}
target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
target = Glide.with(service)
.asBitmapPalette()
.songCoverOptions(song)
.load(RetroGlideExtension.getSongModel(song))
.apply(RequestOptions.circleCropTransform())
.into(object : CustomTarget<BitmapPaletteWrapper>(imageSize, imageSize) {

View file

@ -30,8 +30,9 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.extensions.getTintedDrawable
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
@ -119,7 +120,9 @@ class AppWidgetClassic : BaseAppWidget() {
if (target != null) {
Glide.with(service).clear(target)
}
target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
target = Glide.with(service)
.asBitmapPalette()
.songCoverOptions(song)
.load(RetroGlideExtension.getSongModel(song))
//.checkIgnoreMediaStore()
.centerCrop()

View file

@ -29,8 +29,9 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.extensions.getTintedDrawable
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
@ -144,7 +145,9 @@ class AppWidgetMD3 : BaseAppWidget() {
if (target != null) {
Glide.with(service).clear(target)
}
target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
target = Glide.with(service)
.asBitmapPalette()
.songCoverOptions(song)
.load(RetroGlideExtension.getSongModel(song))
.centerCrop()
.into(object : CustomTarget<BitmapPaletteWrapper>(imageSize, imageSize) {

View file

@ -29,8 +29,9 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.appwidgets.base.BaseAppWidget
import code.name.monkey.retromusic.extensions.getTintedDrawable
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
@ -122,7 +123,9 @@ class AppWidgetSmall : BaseAppWidget() {
if (target != null) {
Glide.with(service).clear(target)
}
target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
target = Glide.with(service)
.asBitmapPalette()
.songCoverOptions(song)
//.checkIgnoreMediaStore()
.load(RetroGlideExtension.getSongModel(song))
.centerCrop()

View file

@ -41,6 +41,10 @@ interface PlaylistDao {
@Query("SELECT * FROM PlaylistEntity")
suspend fun playlistsWithSongs(): List<PlaylistWithSongs>
@Transaction
@Query("SELECT * FROM PlaylistEntity WHERE playlist_id= :playlistId")
fun getPlaylist(playlistId: Long): LiveData<PlaylistWithSongs>
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertSongsToPlaylist(songEntities: List<SongEntity>)

View file

@ -145,3 +145,9 @@ fun List<Song>.toSongsEntity(playlistEntity: PlaylistEntity): List<SongEntity> {
it.toSongEntity(playlistEntity.playListId)
}
}
fun List<Song>.toSongsEntity(playlistId: Long): List<SongEntity> {
return map {
it.toSongEntity(playlistId)
}
}

View file

@ -27,10 +27,10 @@ import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.model.Song
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
class AddToPlaylistDialog : DialogFragment() {
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private val libraryViewModel by activityViewModel<LibraryViewModel>()
companion object {
fun create(playlistEntities: List<PlaylistEntity>, song: Song): AddToPlaylistDialog {
@ -58,8 +58,8 @@ class AddToPlaylistDialog : DialogFragment() {
playlistNames.add(entity.playlistName)
}
return materialDialog(R.string.add_playlist_title)
.setItems(playlistNames.toTypedArray()) { dialog, which->
if (which == 0) {
.setItems(playlistNames.toTypedArray()) { dialog, which ->
if (which == 0) {
showCreateDialog(songs)
} else {
libraryViewModel.addToPlaylist(requireContext(), playlistNames[which], songs)

View file

@ -29,12 +29,12 @@ import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.model.Song
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
class CreatePlaylistDialog : DialogFragment() {
private var _binding: DialogPlaylistBinding? = null
private val binding get() = _binding!!
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private val libraryViewModel by activityViewModel<LibraryViewModel>()
companion object {
fun create(song: Song): CreatePlaylistDialog {

View file

@ -27,11 +27,11 @@ import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
class DeletePlaylistDialog : DialogFragment() {
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private val libraryViewModel by activityViewModel<LibraryViewModel>()
companion object {
@ -55,10 +55,13 @@ class DeletePlaylistDialog : DialogFragment() {
//noinspection ConstantConditions
if (playlists.size > 1) {
title = R.string.delete_playlists_title
message = String.format(getString(R.string.delete_x_playlists), playlists.size).parseAsHtml()
message =
String.format(getString(R.string.delete_x_playlists), playlists.size).parseAsHtml()
} else {
title = R.string.delete_playlist_title
message = String.format(getString(R.string.delete_playlist_x), playlists[0].playlistName).parseAsHtml()
message =
String.format(getString(R.string.delete_playlist_x), playlists[0].playlistName)
.parseAsHtml()
}
return materialDialog(title)

View file

@ -21,10 +21,10 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
class ImportPlaylistDialog : DialogFragment() {
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private val libraryViewModel by activityViewModel<LibraryViewModel>()
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return materialDialog(R.string.import_playlist)

View file

@ -26,10 +26,10 @@ import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
import code.name.monkey.retromusic.fragments.LibraryViewModel
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
class RemoveSongFromPlaylistDialog : DialogFragment() {
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private val libraryViewModel by activityViewModel<LibraryViewModel>()
companion object {
fun create(song: SongEntity): RemoveSongFromPlaylistDialog {

View file

@ -29,11 +29,11 @@ import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
class RenamePlaylistDialog : DialogFragment() {
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private val libraryViewModel by activityViewModel<LibraryViewModel>()
companion object {
fun create(playlistEntity: PlaylistEntity): RenamePlaylistDialog {

View file

@ -19,6 +19,7 @@ import android.content.Context
import android.os.Bundle
import android.text.Spanned
import android.util.Log
import androidx.core.os.BundleCompat
import androidx.core.os.bundleOf
import androidx.core.text.parseAsHtml
import androidx.fragment.app.DialogFragment
@ -38,7 +39,7 @@ class SongDetailDialog : DialogFragment() {
val context: Context = requireContext()
val binding = DialogFileDetailsBinding.inflate(layoutInflater)
val song = requireArguments().getParcelable<Song>(EXTRA_SONG)
val song = BundleCompat.getParcelable(requireArguments(), EXTRA_SONG, Song::class.java)
with(binding) {
fileName.text = makeTextWithTitle(context, R.string.label_file_name, "-")
filePath.text = makeTextWithTitle(context, R.string.label_file_path, "-")

View file

@ -17,6 +17,7 @@ package code.name.monkey.retromusic.dialogs
import android.app.Dialog
import android.content.Intent
import android.os.Bundle
import androidx.core.os.BundleCompat
import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import code.name.monkey.retromusic.EXTRA_SONG
@ -29,7 +30,7 @@ import code.name.monkey.retromusic.util.MusicUtil
class SongShareDialog : DialogFragment() {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val song: Song? = requireArguments().getParcelable(EXTRA_SONG)
val song: Song? = BundleCompat.getParcelable(requireArguments(), EXTRA_SONG, Song::class.java)
val listening: String =
String.format(
getString(R.string.currently_listening_to_x_by_x),

View file

@ -20,6 +20,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.DimenRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.BundleCompat
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import com.google.android.material.appbar.MaterialToolbar

View file

@ -30,12 +30,12 @@ import code.name.monkey.retromusic.extensions.openUrl
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.util.NavigationUtil
import dev.chrisbanes.insetter.applyInsetter
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
private var _binding: FragmentAboutBinding? = null
private val binding get() = _binding!!
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private val libraryViewModel by activityViewModel<LibraryViewModel>()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

View file

@ -18,7 +18,11 @@ import android.app.ActivityOptions
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.view.*
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.SubMenu
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
import androidx.core.text.parseAsHtml
@ -43,10 +47,16 @@ import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
import code.name.monkey.retromusic.databinding.FragmentAlbumDetailsBinding
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.applyColor
import code.name.monkey.retromusic.extensions.applyOutlineColor
import code.name.monkey.retromusic.extensions.findActivityNavController
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.albumCoverOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.artistImageOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.SingleColorTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder.AlbumSongSortOrder.Companion.SONG_A_Z
@ -59,7 +69,12 @@ import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.network.Result
import code.name.monkey.retromusic.network.model.LastFmAlbum
import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.util.*
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.logD
import code.name.monkey.retromusic.util.logE
import com.bumptech.glide.Glide
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.transition.MaterialArcMotion
import com.google.android.material.transition.MaterialContainerTransform
@ -230,9 +245,11 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
is Result.Loading -> {
logD("Loading")
}
is Result.Error -> {
logE("Error")
}
is Result.Success -> {
aboutAlbum(result.data)
}
@ -285,7 +302,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
detailsViewModel.getMoreAlbums(artist).observe(viewLifecycleOwner) {
moreAlbums(it)
}
GlideApp.with(requireContext())
Glide.with(requireContext())
//.forceDownload(PreferenceUtil.isAllowedToDownloadMetadata())
.load(
RetroGlideExtension.getArtistModel(
@ -300,7 +317,8 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
}
private fun loadAlbumCover(album: Album) {
GlideApp.with(requireContext()).asBitmapPalette()
Glide.with(requireContext())
.asBitmapPalette()
.albumCoverOptions(album.safeGetFirstSong())
//.checkIgnoreMediaStore()
.load(RetroGlideExtension.getSongModel(album.safeGetFirstSong()))
@ -332,7 +350,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.menu_album_detail, menu)
val sortOrder = menu.findItem(R.id.action_sort_order)
setUpSortOrderMenu(sortOrder.subMenu)
setUpSortOrderMenu(sortOrder.subMenu!!)
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
requireContext(),
binding.toolbar,
@ -354,10 +372,12 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
MusicPlayerRemote.playNext(songs)
return true
}
R.id.action_add_to_current_playing -> {
MusicPlayerRemote.enqueue(songs)
return true
}
R.id.action_add_to_playlist -> {
lifecycleScope.launch(Dispatchers.IO) {
val playlists = get<RealRepository>().fetchPlaylists()
@ -368,10 +388,12 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
}
return true
}
R.id.action_delete_from_device -> {
DeleteSongsDialog.create(songs).show(childFragmentManager, "DELETE_SONGS")
return true
}
R.id.action_tag_editor -> {
val intent = Intent(requireContext(), AlbumTagEditorActivity::class.java)
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, album.id)
@ -385,6 +407,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
)
return true
}
R.id.action_sort_order_title -> sortOrder = SONG_A_Z
R.id.action_sort_order_title_desc -> sortOrder = SONG_Z_A
R.id.action_sort_order_track_list -> sortOrder = SONG_TRACK_LIST
@ -403,6 +426,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked = true
SONG_TRACK_LIST ->
sortOrder.findItem(R.id.action_sort_order_track_list).isChecked = true
SONG_DURATION ->
sortOrder.findItem(R.id.action_sort_order_artist_song_duration).isChecked = true
}
@ -416,19 +440,23 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
o2.trackNumber
)
}
SONG_A_Z -> {
val collator = Collator.getInstance()
album.songs.sortedWith { o1, o2 -> collator.compare(o1.title, o2.title) }
}
SONG_Z_A -> {
val collator = Collator.getInstance()
album.songs.sortedWith { o1, o2 -> collator.compare(o2.title, o1.title) }
}
SONG_DURATION -> album.songs.sortedWith { o1, o2 ->
o1.duration.compareTo(
o2.duration
)
}
else -> throw IllegalArgumentException("invalid $sortOrder")
}
album = album.copy(songs = songs)

View file

@ -148,10 +148,10 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
if (RetroUtil.isLandscape) {
gridSizeItem.setTitle(R.string.action_grid_size_land)
}
setUpGridSizeMenu(gridSizeItem.subMenu)
setUpGridSizeMenu(gridSizeItem.subMenu!!)
val layoutItem = menu.findItem(R.id.action_layout_type)
setupLayoutMenu(layoutItem.subMenu)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
setupLayoutMenu(layoutItem.subMenu!!)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu!!)
//Setting up cast button
requireContext().setUpMediaRouteButton(menu)
}

View file

@ -27,10 +27,15 @@ import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
import code.name.monkey.retromusic.databinding.FragmentArtistDetailsBinding
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.applyColor
import code.name.monkey.retromusic.extensions.applyOutlineColor
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.artistImageOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.SingleColorTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder
@ -39,14 +44,20 @@ import code.name.monkey.retromusic.model.Artist
import code.name.monkey.retromusic.network.Result
import code.name.monkey.retromusic.network.model.LastFmArtist
import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.util.*
import code.name.monkey.retromusic.util.CustomArtistImageUtil
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import code.name.monkey.retromusic.util.logD
import code.name.monkey.retromusic.util.logE
import com.bumptech.glide.Glide
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.transition.MaterialContainerTransform
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.get
import java.util.*
import java.util.Locale
abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_details),
IAlbumClickListener {
@ -203,7 +214,9 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
}
private fun loadArtistImage(artist: Artist) {
GlideApp.with(requireContext()).asBitmapPalette().artistImageOptions(artist)
Glide.with(requireContext())
.asBitmapPalette()
.artistImageOptions(artist)
.load(RetroGlideExtension.getArtistModel(artist))
.dontAnimate()
.into(object : SingleColorTarget(binding.image) {
@ -243,10 +256,12 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
MusicPlayerRemote.playNext(songs)
return true
}
R.id.action_add_to_current_playing -> {
MusicPlayerRemote.enqueue(songs)
return true
}
R.id.action_add_to_playlist -> {
lifecycleScope.launch(Dispatchers.IO) {
val playlists = get<RealRepository>().fetchPlaylists()
@ -257,6 +272,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
}
return true
}
R.id.action_set_artist_image -> {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "image/*"
@ -268,6 +284,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
)
return true
}
R.id.action_reset_artist_image -> {
showToast(resources.getString(R.string.updating))
lifecycleScope.launch {
@ -315,14 +332,19 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
when (savedSongSortOrder) {
SortOrder.ArtistSongSortOrder.SONG_A_Z -> sortOrder.findItem(R.id.action_sort_order_title).isChecked =
true
SortOrder.ArtistSongSortOrder.SONG_Z_A -> sortOrder.findItem(R.id.action_sort_order_title_desc).isChecked =
true
SortOrder.ArtistSongSortOrder.SONG_ALBUM ->
sortOrder.findItem(R.id.action_sort_order_album).isChecked = true
SortOrder.ArtistSongSortOrder.SONG_YEAR ->
sortOrder.findItem(R.id.action_sort_order_year).isChecked = true
SortOrder.ArtistSongSortOrder.SONG_DURATION ->
sortOrder.findItem(R.id.action_sort_order_song_duration).isChecked = true
else -> {
throw IllegalArgumentException("invalid $savedSongSortOrder")
}

View file

@ -159,10 +159,10 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
if (RetroUtil.isLandscape) {
gridSizeItem.setTitle(R.string.action_grid_size_land)
}
setUpGridSizeMenu(gridSizeItem.subMenu)
setUpGridSizeMenu(gridSizeItem.subMenu!!)
val layoutItem = menu.findItem(R.id.action_layout_type)
setupLayoutMenu(layoutItem.subMenu)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
setupLayoutMenu(layoutItem.subMenu!!)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu!!)
setupAlbumArtistMenu(menu)
//Setting up cast button
requireContext().setUpMediaRouteButton(menu)

View file

@ -22,18 +22,18 @@ import androidx.core.view.MenuProvider
import androidx.lifecycle.Lifecycle
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.fragments.LibraryViewModel
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
abstract class AbsMainActivityFragment(@LayoutRes layout: Int) : AbsMusicServiceFragment(layout),
MenuProvider {
val libraryViewModel: LibraryViewModel by sharedViewModel()
val libraryViewModel: LibraryViewModel by activityViewModel()
val mainActivity: MainActivity
get() = activity as MainActivity
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val menuHost: MenuHost = requireActivity() as MenuHost
val menuHost: MenuHost = requireActivity()
menuHost.addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.STARTED)
}
}

View file

@ -65,13 +65,13 @@ import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
import kotlin.math.abs
abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragment(layout),
Toolbar.OnMenuItemClickListener, IPaletteColorHolder, PlayerAlbumCoverFragment.Callbacks {
val libraryViewModel: LibraryViewModel by sharedViewModel()
val libraryViewModel: LibraryViewModel by activityViewModel()
val mainActivity: MainActivity
get() = activity as MainActivity
@ -87,6 +87,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
PlaybackSpeedDialog.newInstance().show(childFragmentManager, "PLAYBACK_SETTINGS")
return true
}
R.id.action_toggle_lyrics -> {
PreferenceUtil.showLyrics = !PreferenceUtil.showLyrics
showLyricsIcon(item)
@ -97,26 +98,32 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
}
return true
}
R.id.action_go_to_lyrics -> {
goToLyrics(requireActivity())
return true
}
R.id.action_toggle_favorite -> {
toggleFavorite(song)
return true
}
R.id.action_share -> {
SongShareDialog.create(song).show(childFragmentManager, "SHARE_SONG")
return true
}
R.id.action_go_to_drive_mode -> {
NavigationUtil.gotoDriveMode(requireActivity())
return true
}
R.id.action_delete_from_device -> {
DeleteSongsDialog.create(song).show(childFragmentManager, "DELETE_SONGS")
return true
}
R.id.action_add_to_playlist -> {
lifecycleScope.launch(IO) {
val playlists = get<RealRepository>().fetchPlaylists()
@ -127,25 +134,30 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
}
return true
}
R.id.action_clear_playing_queue -> {
MusicPlayerRemote.clearQueue()
return true
}
R.id.action_save_playing_queue -> {
CreatePlaylistDialog.create(ArrayList(MusicPlayerRemote.playingQueue))
.show(childFragmentManager, "ADD_TO_PLAYLIST")
return true
}
R.id.action_tag_editor -> {
val intent = Intent(activity, SongTagEditorActivity::class.java)
intent.putExtra(AbsTagEditorActivity.EXTRA_ID, song.id)
startActivity(intent)
return true
}
R.id.action_details -> {
SongDetailDialog.create(song).show(childFragmentManager, "SONG_DETAIL")
return true
}
R.id.action_go_to_album -> {
//Hide Bottom Bar First, else Bottom Sheet doesn't collapse fully
mainActivity.setBottomNavVisibility(false)
@ -156,10 +168,12 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
)
return true
}
R.id.action_go_to_artist -> {
goToArtist(requireActivity())
return true
}
R.id.now_playing -> {
requireActivity().findNavController(R.id.fragment_container).navigate(
R.id.playing_queue_fragment,
@ -169,18 +183,22 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
mainActivity.collapsePanel()
return true
}
R.id.action_show_lyrics -> {
goToLyrics(requireActivity())
return true
}
R.id.action_equalizer -> {
NavigationUtil.openEqualizer(requireActivity())
return true
}
R.id.action_sleep_timer -> {
SleepTimerDialog().show(parentFragmentManager, "SLEEP_TIMER")
return true
}
R.id.action_set_as_ringtone -> {
requireContext().run {
if (RingtoneManager.requiresDialog(this)) {
@ -192,6 +210,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
return true
}
R.id.action_go_to_genre -> {
val retriever = MediaMetadataRetriever()
val trackUri =
@ -352,8 +371,8 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
context,
object : GestureDetector.SimpleOnGestureListener() {
override fun onScroll(
e1: MotionEvent?,
e2: MotionEvent?,
e1: MotionEvent,
e2: MotionEvent,
distanceX: Float,
distanceY: Float,
): Boolean {
@ -363,6 +382,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
view.parent.requestDisallowInterceptTouchEvent(true)
true
}
else -> {
false
}
@ -371,7 +391,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragme
})
@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View, event: MotionEvent?): Boolean {
override fun onTouch(v: View, event: MotionEvent): Boolean {
viewPager?.dispatchTouchEvent(event)
return flingPlayBackController.onTouchEvent(event)
}

View file

@ -17,11 +17,16 @@ import android.content.Context
import android.media.MediaScannerConnection
import android.os.Bundle
import android.os.Environment
import android.view.*
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.webkit.MimeTypeMap
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.widget.PopupMenu
import androidx.appcompat.widget.Toolbar
import androidx.core.os.BundleCompat
import androidx.core.text.parseAsHtml
import androidx.core.view.isVisible
import androidx.core.view.updateLayoutParams
@ -50,6 +55,7 @@ import code.name.monkey.retromusic.helper.menu.SongMenuHelper
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.ICallbacks
import code.name.monkey.retromusic.interfaces.IMainActivityFragmentCallbacks
import code.name.monkey.retromusic.interfaces.IScrollHelper
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener
import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader
import code.name.monkey.retromusic.model.Song
@ -59,6 +65,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil.startDirectory
import code.name.monkey.retromusic.util.ThemedFastScroller.create
import code.name.monkey.retromusic.util.getExternalStorageDirectory
import code.name.monkey.retromusic.util.getExternalStoragePublicDirectory
import code.name.monkey.retromusic.views.BreadCrumbLayout
import code.name.monkey.retromusic.views.BreadCrumbLayout.Crumb
import code.name.monkey.retromusic.views.BreadCrumbLayout.SelectionCallback
import com.google.android.material.snackbar.Snackbar
@ -70,11 +77,12 @@ import java.io.File
import java.io.FileFilter
import java.io.IOException
import java.lang.ref.WeakReference
import java.util.*
import java.util.Collections
import java.util.LinkedList
class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
IMainActivityFragmentCallbacks, SelectionCallback, ICallbacks,
LoaderManager.LoaderCallbacks<List<File>>, StorageClickListener {
LoaderManager.LoaderCallbacks<List<File>>, StorageClickListener, IScrollHelper {
private var _binding: FragmentFolderBinding? = null
private val binding get() = _binding!!
@ -113,21 +121,10 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
override fun handleOnBackPressed() {
if (!handleBackPress()) {
remove()
requireActivity().onBackPressed()
requireActivity().onBackPressedDispatcher.onBackPressed()
}
}
})
}
private fun setUpTitle() {
toolbar.setNavigationOnClickListener {
findNavController().navigate(R.id.action_search, null, navOptions)
}
binding.appBarLayout.title = resources.getString(R.string.folders)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (savedInstanceState == null) {
switchToFileAdapter()
setCrumb(
@ -137,11 +134,31 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
true
)
} else {
binding.breadCrumbs.restoreFromStateWrapper(savedInstanceState.getParcelable(CRUMBS))
binding.breadCrumbs.restoreFromStateWrapper(
BundleCompat.getParcelable(
savedInstanceState,
CRUMBS,
BreadCrumbLayout.SavedStateWrapper::class.java
)
)
LoaderManager.getInstance(this).initLoader(LOADER_ID, null, this)
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
if (_binding != null) {
outState.putParcelable(CRUMBS, binding.breadCrumbs.stateWrapper)
}
}
private fun setUpTitle() {
toolbar.setNavigationOnClickListener {
findNavController().navigate(R.id.action_search, null, navOptions)
}
binding.appBarLayout.title = resources.getString(R.string.folders)
}
override fun onPause() {
super.onPause()
saveScrollPosition()
@ -187,10 +204,12 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
}
return@setOnMenuItemClickListener true
}
R.id.action_add_to_blacklist -> {
BlacklistStore.getInstance(requireContext()).addPath(file)
return@setOnMenuItemClickListener true
}
R.id.action_set_as_start_directory -> {
startDirectory = file
showToast(
@ -198,6 +217,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
)
return@setOnMenuItemClickListener true
}
R.id.action_scan -> {
lifecycleScope.launch {
listPaths(file, AUDIO_FILE_FILTER) { paths -> scanPaths(paths) }
@ -229,6 +249,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
}
return@setOnMenuItemClickListener true
}
R.id.action_scan -> {
lifecycleScope.launch {
listPaths(file, AUDIO_FILE_FILTER) { paths -> scanPaths(paths) }
@ -353,6 +374,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
)
return true
}
R.id.action_scan -> {
val crumb = activeCrumb
if (crumb != null) {
@ -362,6 +384,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
}
return true
}
R.id.action_settings -> {
findNavController().navigate(
R.id.settings_fragment,
@ -404,13 +427,11 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
}
private fun saveScrollPosition() {
val crumb = activeCrumb
if (crumb != null) {
crumb.scrollPosition =
(binding.recyclerView.layoutManager as LinearLayoutManager?)!!.findFirstVisibleItemPosition()
}
activeCrumb?.scrollPosition =
(binding.recyclerView.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
}
private fun scanPaths(toBeScanned: Array<String?>) {
if (activity == null) {
return
@ -470,8 +491,8 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
adapter?.swapDataSet(files)
val crumb = activeCrumb
if (crumb != null) {
(binding.recyclerView.layoutManager as LinearLayoutManager?)
?.scrollToPositionWithOffset(crumb.scrollPosition, 0)
(binding.recyclerView.layoutManager as LinearLayoutManager)
.scrollToPositionWithOffset(crumb.scrollPosition, 0)
}
}
@ -535,7 +556,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
}
}
suspend fun listSongs(
private suspend fun listSongs(
context: Context,
files: List<File?>,
fileFilter: FileFilter,
@ -565,6 +586,11 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
)
}
override fun scrollToTop() {
binding.recyclerView.scrollToPosition(0)
binding.appBarLayout.setExpanded(true, true)
}
private fun switchToFileAdapter() {
adapter = SongFileAdapter(mainActivity, LinkedList(), R.layout.item_list, this)
adapter!!.registerAdapterDataObserver(

View file

@ -9,7 +9,7 @@ class HomeBinding(
val container = homeBinding.container
val contentContainer = homeBinding.contentContainer
val appBarLayout = homeBinding.appBarLayout
val toolbar = homeBinding.toolbar
val toolbar = homeBinding.appBarLayout.toolbar
val bannerImage = homeBinding.imageLayout.bannerImage
val userImage = homeBinding.imageLayout.userImage
val lastAdded = homeBinding.homeContent.absPlaylists.lastAdded
@ -18,6 +18,5 @@ class HomeBinding(
val history = homeBinding.homeContent.absPlaylists.history
val recyclerView = homeBinding.homeContent.recyclerView
val titleWelcome = homeBinding.imageLayout.titleWelcome
val appNameText = homeBinding.appNameText
val suggestions = homeBinding.homeContent.suggestions
}

View file

@ -15,8 +15,12 @@
package code.name.monkey.retromusic.fragments.home
import android.os.Bundle
import android.view.*
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM
import android.view.View
import android.view.ViewGroup
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.os.bundleOf
import androidx.core.text.parseAsHtml
@ -30,21 +34,32 @@ import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.EXTRA_PLAYLIST_TYPE
import code.name.monkey.retromusic.HISTORY_PLAYLIST
import code.name.monkey.retromusic.LAST_ADDED_PLAYLIST
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.TOP_PLAYED_PLAYLIST
import code.name.monkey.retromusic.adapter.HomeAdapter
import code.name.monkey.retromusic.databinding.FragmentHomeBinding
import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.dip
import code.name.monkey.retromusic.extensions.drawNextToNavbar
import code.name.monkey.retromusic.extensions.elevatedAccentColor
import code.name.monkey.retromusic.extensions.setUpMediaRouteButton
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.profileBannerOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.userProfileOptions
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.IScrollHelper
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.PreferenceUtil.userName
import com.bumptech.glide.Glide
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.transition.MaterialFadeThrough
import com.google.android.material.transition.MaterialSharedAxis
@ -86,9 +101,6 @@ class HomeFragment :
colorButtons()
postponeEnterTransition()
view.doOnPreDraw { startPostponedEnterTransition() }
binding.appBarLayout.statusBarForeground =
MaterialShapeDrawable.createWithElevationOverlay(requireContext())
binding.toolbar.drawNextToNavbar()
view.doOnLayout {
adjustPlaylistButtons()
}
@ -163,18 +175,18 @@ class HomeFragment :
findNavController().navigate(R.id.action_search, null, navOptions)
}
val hexColor = String.format("#%06X", 0xFFFFFF and accentColor())
val appName = "Retro <span style='color:$hexColor';>Music</span>".parseAsHtml()
binding.appNameText.text = appName
val appName = "<font color=$hexColor>Retro Music</font>".parseAsHtml()
binding.appBarLayout.title = appName
}
private fun loadProfile() {
binding.bannerImage?.let {
GlideApp.with(requireContext())
Glide.with(requireContext())
.load(RetroGlideExtension.getBannerModel())
.profileBannerOptions(RetroGlideExtension.getBannerModel())
.into(it)
}
GlideApp.with(requireActivity())
Glide.with(requireActivity())
.load(RetroGlideExtension.getUserModel())
.userProfileOptions(RetroGlideExtension.getUserModel(), requireContext())
.into(binding.userImage)
@ -265,7 +277,7 @@ class HomeFragment :
MusicPlayerRemote.playNextSong()
}
}
GlideApp.with(this)
Glide.with(this)
.load(RetroGlideExtension.getSongModel(songs[index]))
.songCoverOptions(songs[index])
.into(imageView)
@ -289,10 +301,12 @@ class HomeFragment :
null,
navOptions
)
R.id.action_import_playlist -> ImportPlaylistDialog().show(
childFragmentManager,
"ImportPlaylist"
)
R.id.action_add_to_playlist -> CreatePlaylistDialog.create(emptyList()).show(
childFragmentManager,
"ShowCreatePlaylistDialog"

View file

@ -31,13 +31,14 @@ import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.textColorPrimary
import code.name.monkey.retromusic.extensions.textColorSecondary
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
import com.bumptech.glide.Glide
import kotlin.math.abs
open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_player),
@ -113,7 +114,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
private fun updateSongCover() {
val song = MusicPlayerRemote.currentSong
GlideApp.with(requireContext())
Glide.with(requireContext())
.load(RetroGlideExtension.getSongModel(song))
.transition(RetroGlideExtension.getDefaultTransition())
.songCoverOptions(song)

View file

@ -37,8 +37,9 @@ import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.applyToolbar
import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.profileBannerOptions
import code.name.monkey.retromusic.glide.RetroGlideExtension.userProfileOptions
import code.name.monkey.retromusic.util.ImageUtil
import code.name.monkey.retromusic.util.PreferenceUtil.userName
import com.bumptech.glide.Glide
@ -54,14 +55,14 @@ import com.google.android.material.transition.MaterialContainerTransform
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
import java.io.File
class UserInfoFragment : Fragment() {
private var _binding: FragmentUserInfoBinding? = null
private val binding get() = _binding!!
private val libraryViewModel: LibraryViewModel by sharedViewModel()
private val libraryViewModel: LibraryViewModel by activityViewModel()
override fun onCreateView(
inflater: LayoutInflater,
@ -155,12 +156,12 @@ class UserInfoFragment : Fragment() {
private fun loadProfile() {
binding.bannerImage.let {
GlideApp.with(this)
Glide.with(this)
.load(RetroGlideExtension.getBannerModel())
.profileBannerOptions(RetroGlideExtension.getBannerModel())
.into(it)
}
GlideApp.with(this)
Glide.with(this)
.load(RetroGlideExtension.getUserModel())
.userProfileOptions(RetroGlideExtension.getUserModel(), requireContext())
.into(binding.userImage)
@ -209,9 +210,11 @@ class UserInfoFragment : Fragment() {
doIfResultOk(uri)
}
}
ImagePicker.RESULT_ERROR -> {
showToast(ImagePicker.getError(data))
}
else -> {
showToast("Task Cancelled")
}

View file

@ -20,7 +20,12 @@ import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.databinding.FragmentAdaptivePlayerBinding
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.colorControlNormal
import code.name.monkey.retromusic.extensions.drawAboveSystemBars
import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.extensions.textColorPrimary
import code.name.monkey.retromusic.extensions.textColorSecondary
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -60,7 +65,7 @@ class AdaptiveFragment : AbsPlayerFragment(R.layout.fragment_adaptive_player) {
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
ToolbarContentTintHelper.colorizeToolbar(this, surfaceColor(), requireActivity())
setTitleTextColor(textColorPrimary())
setSubtitleTextColor(textColorSecondary())

View file

@ -30,17 +30,22 @@ import code.name.monkey.retromusic.extensions.drawAboveSystemBars
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.glide.*
import code.name.monkey.retromusic.glide.BlurTransformation
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.simpleSongCoverOptions
import code.name.monkey.retromusic.glide.crossfadeListener
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil.blurAmount
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder
class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur),
SharedPreferences.OnSharedPreferenceChangeListener {
private var lastRequest: GlideRequest<Drawable>? = null
private var lastRequest: RequestBuilder<Drawable>? = null
override fun playerToolbar(): Toolbar {
return binding.playerToolbar
@ -72,7 +77,7 @@ class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur),
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
ToolbarContentTintHelper.colorizeToolbar(this, Color.WHITE, activity)
}.setOnMenuItemClickListener(this)
}
@ -114,14 +119,14 @@ class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur),
private fun updateBlur() {
// https://github.com/bumptech/glide/issues/527#issuecomment-148840717
GlideApp.with(this)
Glide.with(this)
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.simpleSongCoverOptions(MusicPlayerRemote.currentSong)
.transform(
BlurTransformation.Builder(requireContext()).blurRadius(blurAmount.toFloat())
.build()
).thumbnail(lastRequest)
.error(GlideApp.with(this).load(ColorDrawable(Color.DKGRAY)).fitCenter())
.error(Glide.with(this).load(ColorDrawable(Color.DKGRAY)).fitCenter())
.also {
lastRequest = it.clone()
it.crossfadeListener()

View file

@ -97,7 +97,7 @@ class CardFragment : AbsPlayerFragment(R.layout.fragment_card_player) {
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
setOnMenuItemClickListener(this@CardFragment)
ToolbarContentTintHelper.colorizeToolbar(this, Color.WHITE, activity)

View file

@ -30,11 +30,16 @@ import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.fragments.player.normal.PlayerFragment
import code.name.monkey.retromusic.glide.*
import code.name.monkey.retromusic.glide.BlurTransformation
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.simpleSongCoverOptions
import code.name.monkey.retromusic.glide.crossfadeListener
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PreferenceUtil.blurAmount
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder
class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
SharedPreferences.OnSharedPreferenceChangeListener {
@ -49,7 +54,7 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
private var _binding: FragmentCardBlurPlayerBinding? = null
private val binding get() = _binding!!
private var lastRequest: GlideRequest<Drawable>? = null
private var lastRequest: RequestBuilder<Drawable>? = null
override fun onShow() {
playbackControlsFragment.show()
@ -108,7 +113,7 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
setTitleTextColor(Color.WHITE)
setSubtitleTextColor(Color.WHITE)
ToolbarContentTintHelper.colorizeToolbar(binding.playerToolbar, Color.WHITE, activity)
@ -138,7 +143,7 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
private fun updateBlur() {
// https://github.com/bumptech/glide/issues/527#issuecomment-148840717
GlideApp.with(this)
Glide.with(this)
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.simpleSongCoverOptions(MusicPlayerRemote.currentSong)
.transform(

View file

@ -38,9 +38,8 @@ import code.name.monkey.retromusic.fragments.MusicSeekSkipTouchListener
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.base.goToAlbum
import code.name.monkey.retromusic.fragments.base.goToArtist
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.GlideRequest
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.simpleSongCoverOptions
import code.name.monkey.retromusic.glide.crossfadeListener
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
@ -51,6 +50,8 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import code.name.monkey.retromusic.volume.AudioVolumeObserver
import code.name.monkey.retromusic.volume.OnAudioVolumeChangedListener
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder
import com.google.android.material.slider.Slider
import me.tankery.lib.circularseekbar.CircularSeekBar
@ -72,9 +73,8 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
private val binding get() = _binding!!
private var rotateAnimator: ObjectAnimator? = null
private var lastRequest: GlideRequest<Drawable>? = null
private var lastRequest: RequestBuilder<Drawable>? = null
private var progressAnimator: ObjectAnimator? = null
var isSeeking = false
override fun onCreate(savedInstanceState: Bundle?) {
@ -100,7 +100,7 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
setOnMenuItemClickListener(this@CirclePlayerFragment)
ToolbarContentTintHelper.colorizeToolbar(
this,
@ -129,8 +129,12 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
private fun setUpPrevNext() {
updatePrevNextColor()
binding.nextButton.setOnTouchListener(MusicSeekSkipTouchListener(requireActivity(), true))
binding.previousButton.setOnTouchListener(MusicSeekSkipTouchListener(requireActivity(),
false))
binding.previousButton.setOnTouchListener(
MusicSeekSkipTouchListener(
requireActivity(),
false
)
)
}
private fun updatePrevNextColor() {
@ -237,11 +241,11 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
} else {
binding.songInfo.hide()
}
GlideApp.with(this)
Glide.with(this)
.load(RetroGlideExtension.getSongModel(MusicPlayerRemote.currentSong))
.simpleSongCoverOptions(MusicPlayerRemote.currentSong)
.thumbnail(lastRequest)
.error(GlideApp.with(this).load(R.drawable.default_audio_art).fitCenter())
.error(Glide.with(this).load(R.drawable.default_audio_art).fitCenter())
.fitCenter().also {
lastRequest = it.clone()
it.crossfadeListener()

View file

@ -102,10 +102,12 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
BottomSheetBehavior.STATE_DRAGGING -> {
mainActivity.getBottomSheetBehavior().isDraggable = false
}
BottomSheetBehavior.STATE_COLLAPSED -> {
resetToCurrentPosition()
mainActivity.getBottomSheetBehavior().isDraggable = true
}
else -> {
mainActivity.getBottomSheetBehavior().isDraggable = true
}
@ -377,7 +379,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
private fun setUpPlayerToolbar() {
binding.playerToolbar.inflateMenu(R.menu.menu_player)
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
binding.playerToolbar.setOnMenuItemClickListener(this)
ToolbarContentTintHelper.colorizeToolbar(
@ -491,6 +493,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
lastPlaybackControlsColor,
PorterDuff.Mode.SRC_IN
)
else -> binding.playerControlsContainer.shuffleButton.setColorFilter(
lastDisabledPlaybackControlsColor,
PorterDuff.Mode.SRC_IN
@ -511,6 +514,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
PorterDuff.Mode.SRC_IN
)
}
MusicService.REPEAT_MODE_ALL -> {
binding.playerControlsContainer.repeatButton.setImageResource(R.drawable.ic_repeat)
binding.playerControlsContainer.repeatButton.setColorFilter(
@ -518,6 +522,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
PorterDuff.Mode.SRC_IN
)
}
MusicService.REPEAT_MODE_THIS -> {
binding.playerControlsContainer.repeatButton.setImageResource(R.drawable.ic_repeat_one)
binding.playerControlsContainer.repeatButton.setColorFilter(

View file

@ -124,7 +124,7 @@ class ColorFragment : AbsPlayerFragment(R.layout.fragment_color_player) {
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
setOnMenuItemClickListener(this@ColorFragment)
ToolbarContentTintHelper.colorizeToolbar(
this,

View file

@ -100,7 +100,7 @@ class FitFragment : AbsPlayerFragment(R.layout.fragment_fit) {
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
setOnMenuItemClickListener(this@FitFragment)
ToolbarContentTintHelper.colorizeToolbar(
this,

View file

@ -61,7 +61,7 @@ class FlatPlayerFragment : AbsPlayerFragment(R.layout.fragment_flat_player) {
private fun setUpPlayerToolbar() {
binding.playerToolbar.inflateMenu(R.menu.menu_player)
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
binding.playerToolbar.setOnMenuItemClickListener(this)
ToolbarContentTintHelper.colorizeToolbar(
binding.playerToolbar,

View file

@ -32,7 +32,11 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.databinding.FragmentFullPlayerControlsBinding
import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.db.toSongEntity
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.applyColor
import code.name.monkey.retromusic.extensions.getSongInfo
import code.name.monkey.retromusic.extensions.getTintedDrawable
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
@ -48,7 +52,7 @@ import com.google.android.material.slider.Slider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
/**
* Created by hemanths on 20/09/17.
@ -58,7 +62,7 @@ class FullPlaybackControlsFragment :
AbsPlayerControlsFragment(R.layout.fragment_full_player_controls),
PopupMenu.OnMenuItemClickListener {
private val libraryViewModel: LibraryViewModel by sharedViewModel()
private val libraryViewModel: LibraryViewModel by activityViewModel()
private var _binding: FragmentFullPlayerControlsBinding? = null
private val binding get() = _binding!!

View file

@ -30,11 +30,12 @@ import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.base.goToArtist
import code.name.monkey.retromusic.fragments.player.CoverLyricsFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.artistImageOptions
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full) {
private var _binding: FragmentFullBinding? = null
@ -51,7 +52,7 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full) {
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
}
}
@ -135,7 +136,7 @@ class FullPlayerFragment : AbsPlayerFragment(R.layout.fragment_full) {
libraryViewModel.artist(MusicPlayerRemote.currentSong.artistId)
.observe(viewLifecycleOwner) { artist ->
if (artist.id != -1L) {
GlideApp.with(requireActivity())
Glide.with(requireActivity())
.load(RetroGlideExtension.getArtistModel(artist))
.artistImageOptions(artist)
.into(binding.artistImage)

View file

@ -122,7 +122,7 @@ class HomePlayerFragment : AbsPlayerFragment(R.layout.fragment_home_player),
private fun setUpPlayerToolbar() {
binding.playerToolbar.inflateMenu(R.menu.menu_player)
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
binding.playerToolbar.setOnMenuItemClickListener(this)
ToolbarContentTintHelper.colorizeToolbar(

View file

@ -144,7 +144,7 @@ class MaterialFragment : AbsPlayerFragment(R.layout.fragment_material) {
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
setOnMenuItemClickListener(this@MaterialFragment)
ToolbarContentTintHelper.colorizeToolbar(
this,

View file

@ -103,7 +103,7 @@ class MD3PlayerFragment : AbsPlayerFragment(R.layout.fragment_md3_player) {
private fun setUpPlayerToolbar() {
binding.playerToolbar.inflateMenu(R.menu.menu_player)
//binding.playerToolbar.menu.setUpWithIcons()
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
binding.playerToolbar.setOnMenuItemClickListener(this)
ToolbarContentTintHelper.colorizeToolbar(

View file

@ -27,7 +27,11 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.SNOWFALL
import code.name.monkey.retromusic.databinding.FragmentPlayerBinding
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.colorControlNormal
import code.name.monkey.retromusic.extensions.drawAboveSystemBars
import code.name.monkey.retromusic.extensions.isColorLight
import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
@ -147,7 +151,7 @@ class PlayerFragment : AbsPlayerFragment(R.layout.fragment_player),
private fun setUpPlayerToolbar() {
binding.playerToolbar.inflateMenu(R.menu.menu_player)
//binding.playerToolbar.menu.setUpWithIcons()
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
binding.playerToolbar.setOnMenuItemClickListener(this)
ToolbarContentTintHelper.colorizeToolbar(

View file

@ -20,7 +20,12 @@ import androidx.appcompat.widget.Toolbar
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.databinding.FragmentPeekPlayerBinding
import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.extensions.colorControlNormal
import code.name.monkey.retromusic.extensions.drawAboveSystemBarsWithPadding
import code.name.monkey.retromusic.extensions.getSongInfo
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
import code.name.monkey.retromusic.fragments.base.goToAlbum
import code.name.monkey.retromusic.fragments.base.goToArtist
@ -68,7 +73,7 @@ class PeekPlayerFragment : AbsPlayerFragment(R.layout.fragment_peek_player) {
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
setOnMenuItemClickListener(this@PeekPlayerFragment)
ToolbarContentTintHelper.colorizeToolbar(
this,

View file

@ -63,7 +63,7 @@ class PlainPlayerFragment : AbsPlayerFragment(R.layout.fragment_plain_player) {
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
setOnMenuItemClickListener(this@PlainPlayerFragment)
ToolbarContentTintHelper.colorizeToolbar(
this,

View file

@ -101,7 +101,7 @@ class SimplePlayerFragment : AbsPlayerFragment(R.layout.fragment_simple_player)
private fun setUpPlayerToolbar() {
binding.playerToolbar.inflateMenu(R.menu.menu_player)
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressed() }
binding.playerToolbar.setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
binding.playerToolbar.setOnMenuItemClickListener(this)
ToolbarContentTintHelper.colorizeToolbar(
binding.playerToolbar,

View file

@ -159,7 +159,7 @@ class TinyPlayerFragment : AbsPlayerFragment(R.layout.fragment_tiny_player),
private fun setUpPlayerToolbar() {
binding.playerToolbar.apply {
inflateMenu(R.menu.menu_player)
setNavigationOnClickListener { requireActivity().onBackPressed() }
setNavigationOnClickListener { requireActivity().onBackPressedDispatcher.onBackPressed() }
setOnMenuItemClickListener(this@TinyPlayerFragment)
}
}
@ -213,8 +213,8 @@ class TinyPlayerFragment : AbsPlayerFragment(R.layout.fragment_tiny_player),
gestureDetector = GestureDetector(context, object :
GestureDetector.SimpleOnGestureListener() {
override fun onLongPress(e: MotionEvent?) {
if (abs(e!!.y - initialY) <= 2) {
override fun onLongPress(e: MotionEvent) {
if (abs(e.y - initialY) <= 2) {
vibrate()
isDragEnabled = true
binding.progressBar.parent.requestDisallowInterceptTouchEvent(true)
@ -251,6 +251,7 @@ class TinyPlayerFragment : AbsPlayerFragment(R.layout.fragment_tiny_player),
initialY = event.y.toInt()
progressViewUpdateHelper.stop()
}
MotionEvent.ACTION_UP,
MotionEvent.ACTION_CANCEL -> {
progressViewUpdateHelper.start()
@ -260,6 +261,7 @@ class TinyPlayerFragment : AbsPlayerFragment(R.layout.fragment_tiny_player),
return true
}
}
MotionEvent.ACTION_MOVE -> {
if (isDragEnabled) {
val diffY = (initialY - event.y).toInt()

View file

@ -14,15 +14,21 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.OrderablePlaylistSongAdapter
import code.name.monkey.retromusic.databinding.FragmentPlaylistDetailBinding
import code.name.monkey.retromusic.databinding.FragmentPlaylistDetailNewBinding
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.toSongs
import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.elevatedAccentColor
import code.name.monkey.retromusic.extensions.surfaceColor
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.RetroGlideExtension.playlistOptions
import code.name.monkey.retromusic.glide.playlistPreview.PlaylistPreview
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.ThemedFastScroller
import com.bumptech.glide.Glide
import com.google.android.material.shape.MaterialShapeDrawable
import com.google.android.material.transition.MaterialArcMotion
import com.google.android.material.transition.MaterialContainerTransform
@ -34,13 +40,13 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_detail) {
class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_detail_new) {
private val arguments by navArgs<PlaylistDetailsFragmentArgs>()
private val viewModel by viewModel<PlaylistDetailsViewModel> {
parametersOf(arguments.extraPlaylist)
parametersOf(arguments.extraPlaylistId)
}
private var _binding: FragmentPlaylistDetailBinding? = null
private var _binding: FragmentPlaylistDetailNewBinding? = null
private val binding get() = _binding!!
private lateinit var playlist: PlaylistWithSongs
@ -58,16 +64,26 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentPlaylistDetailBinding.bind(view)
_binding = FragmentPlaylistDetailNewBinding.bind(view)
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).addTarget(view)
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
mainActivity.setSupportActionBar(binding.toolbar)
binding.container.transitionName = "playlist"
playlist = arguments.extraPlaylist
binding.toolbar.title = playlist.playlistEntity.playlistName
binding.toolbar.subtitle =
MusicUtil.getPlaylistInfoString(requireContext(), playlist.songs.toSongs())
binding.toolbar.title = null
// binding.container.transitionName = playlist.playlistEntity.playlistName
setUpRecyclerView()
setupButtons()
viewModel.getPlaylist().observe(viewLifecycleOwner) { playlistWithSongs ->
playlist = playlistWithSongs
Glide.with(this)
.load(PlaylistPreview(playlistWithSongs))
.playlistOptions()
.into(binding.image)
binding.title.text = playlist.playlistEntity.playlistName
binding.subtitle.text =
MusicUtil.getPlaylistInfoString(requireContext(), playlist.songs.toSongs())
binding.collapsingAppBarLayout.title = playlist.playlistEntity.playlistName
}
viewModel.getSongs().observe(viewLifecycleOwner) {
songs(it.toSongs())
}
@ -82,9 +98,24 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
MaterialShapeDrawable.createWithElevationOverlay(requireContext())
}
private fun setupButtons() {
binding.playButton.apply {
setOnClickListener {
MusicPlayerRemote.openQueue(playlistSongAdapter.dataSet, 0, true)
}
accentColor()
}
binding.shuffleButton.apply {
setOnClickListener {
MusicPlayerRemote.openAndShuffleQueue(playlistSongAdapter.dataSet, true)
}
elevatedAccentColor()
}
}
private fun setUpRecyclerView() {
playlistSongAdapter = OrderablePlaylistSongAdapter(
playlist.playlistEntity,
arguments.extraPlaylistId,
requireActivity(),
ArrayList(),
R.layout.item_queue

View file

@ -18,15 +18,18 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
import code.name.monkey.retromusic.db.PlaylistWithSongs
import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.repository.RealRepository
class PlaylistDetailsViewModel(
private val realRepository: RealRepository,
private var playlist: PlaylistWithSongs
private var playlistId: Long
) : ViewModel() {
fun getSongs(): LiveData<List<SongEntity>> =
realRepository.playlistSongs(playlist.playlistEntity.playListId)
realRepository.playlistSongs(playlistId)
fun playlistExists(): LiveData<Boolean> =
realRepository.checkPlaylistExists(playlist.playlistEntity.playListId)
realRepository.checkPlaylistExists(playlistId)
fun getPlaylist(): LiveData<PlaylistWithSongs> = realRepository.getPlaylist(playlistId)
}

View file

@ -21,6 +21,7 @@ import androidx.core.view.MenuCompat
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.EXTRA_PLAYLIST_ID
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.playlist.PlaylistAdapter
import code.name.monkey.retromusic.db.PlaylistWithSongs
@ -76,12 +77,12 @@ class PlaylistsFragment :
if (RetroUtil.isLandscape) {
gridSizeItem.setTitle(R.string.action_grid_size_land)
}
setupGridSizeMenu(gridSizeItem.subMenu)
setupGridSizeMenu(gridSizeItem.subMenu!!)
menu.removeItem(R.id.action_layout_type)
menu.add(0, R.id.action_add_to_playlist, 0, R.string.new_playlist_title)
menu.add(0, R.id.action_import_playlist, 0, R.string.import_playlist)
menu.findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu!!)
MenuCompat.setGroupDividerEnabled(menu, true)
//Setting up cast button
requireContext().setUpMediaRouteButton(menu)
@ -244,7 +245,7 @@ class PlaylistsFragment :
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
findNavController().navigate(
R.id.playlistDetailsFragment,
bundleOf(EXTRA_PLAYLIST to playlistWithSongs)
bundleOf(EXTRA_PLAYLIST_ID to playlistWithSongs.playlistEntity.playListId)
)
}
}

View file

@ -24,14 +24,14 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.installLanguageAndRecreate
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.ReloadType.HomeSections
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import org.koin.androidx.viewmodel.ext.android.activityViewModel
/**
* @author Hemanth S (h4h13).
*/
class OtherSettingsFragment : AbsSettingsFragment() {
private val libraryViewModel by sharedViewModel<LibraryViewModel>()
private val libraryViewModel by activityViewModel<LibraryViewModel>()
override fun invalidateSettings() {
val languagePreference: ATEListPreference? = findPreference(LANGUAGE_NAME)

View file

@ -17,6 +17,7 @@ package code.name.monkey.retromusic.fragments.settings
import android.os.Bundle
import android.view.View
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEListPreference
import code.name.monkey.retromusic.APPBAR_MODE
import code.name.monkey.retromusic.HOME_ALBUM_GRID_STYLE
import code.name.monkey.retromusic.HOME_ARTIST_GRID_STYLE
import code.name.monkey.retromusic.R
@ -47,5 +48,10 @@ class PersonalizeSettingsFragment : AbsSettingsFragment() {
setSummary(prefs, newValue)
true
}
val appBarMode: ATEListPreference? = findPreference(APPBAR_MODE)
appBarMode?.setOnPreferenceChangeListener { _, _ ->
restartActivity()
true
}
}
}

View file

@ -39,14 +39,18 @@ class SettingsFragment : Fragment(R.layout.fragment_settings), ColorCallback {
}
private fun setupToolbar() {
applyToolbar(binding.toolbar)
binding.toolbar.setNavigationOnClickListener {
requireActivity().onBackPressed()
}
val navController: NavController = findNavController(R.id.contentFrame)
with (binding.appBarLayout.toolbar) {
setNavigationIcon(R.drawable.ic_arrow_back)
isTitleCentered = false
setNavigationOnClickListener {
requireActivity().onBackPressedDispatcher.onBackPressed()
}
}
navController.addOnDestinationChangedListener { _, _, _ ->
binding.collapsingToolbarLayout.title =
navController.currentDestination?.let { getStringFromDestination(it) }
binding.appBarLayout.title =
navController.currentDestination?.let { getStringFromDestination(it) }.toString()
}
}

View file

@ -114,10 +114,10 @@ class SongsFragment : AbsRecyclerViewCustomGridSizeFragment<SongAdapter, GridLay
if (RetroUtil.isLandscape) {
gridSizeItem.setTitle(R.string.action_grid_size_land)
}
setUpGridSizeMenu(gridSizeItem.subMenu)
setUpGridSizeMenu(gridSizeItem.subMenu!!)
val layoutItem = menu.findItem(R.id.action_layout_type)
setupLayoutMenu(layoutItem.subMenu)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
setupLayoutMenu(layoutItem.subMenu!!)
setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu!!)
//Setting up cast button
requireContext().setUpMediaRouteButton(menu)
}

View file

@ -23,14 +23,11 @@ import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.GenericTransitionOptions
import com.bumptech.glide.Priority
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.annotation.GlideExtension
import com.bumptech.glide.annotation.GlideOption
import com.bumptech.glide.annotation.GlideType
import com.bumptech.glide.RequestManager
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.Key
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.BaseRequestOptions
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.target.Target.SIZE_ORIGINAL
@ -40,7 +37,6 @@ import com.bumptech.glide.signature.MediaStoreSignature
import java.io.File
@GlideExtension
object RetroGlideExtension {
private const val DEFAULT_ARTIST_IMAGE =
@ -54,10 +50,8 @@ object RetroGlideExtension {
private const val DEFAULT_ANIMATION = android.R.anim.fade_in
@JvmStatic
@GlideType(BitmapPaletteWrapper::class)
fun asBitmapPalette(requestBuilder: RequestBuilder<BitmapPaletteWrapper>): RequestBuilder<BitmapPaletteWrapper> {
return requestBuilder
fun RequestManager.asBitmapPalette(): RequestBuilder<BitmapPaletteWrapper> {
return this.`as`(BitmapPaletteWrapper::class.java)
}
private fun getSongModel(song: Song, ignoreMediaStore: Boolean): Any {
@ -100,14 +94,10 @@ object RetroGlideExtension {
}
}
@JvmStatic
@GlideOption
fun artistImageOptions(
baseRequestOptions: BaseRequestOptions<*>,
fun <T> RequestBuilder<T>.artistImageOptions(
artist: Artist
): BaseRequestOptions<*> {
return baseRequestOptions
.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY_ARTIST)
): RequestBuilder<T> {
return diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY_ARTIST)
.priority(Priority.LOW)
.error(getDrawable(DEFAULT_ARTIST_IMAGE))
.placeholder(getDrawable(DEFAULT_ARTIST_IMAGE))
@ -115,70 +105,52 @@ object RetroGlideExtension {
.signature(createSignature(artist))
}
@JvmStatic
@GlideOption
fun songCoverOptions(
baseRequestOptions: BaseRequestOptions<*>,
fun <T> RequestBuilder<T>.songCoverOptions(
song: Song
): BaseRequestOptions<*> {
return baseRequestOptions.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
): RequestBuilder<T> {
return diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(getDrawable(DEFAULT_SONG_IMAGE))
.placeholder(getDrawable(DEFAULT_SONG_IMAGE))
.signature(createSignature(song))
}
@JvmStatic
@GlideOption
fun simpleSongCoverOptions(
baseRequestOptions: BaseRequestOptions<*>,
fun <T> RequestBuilder<T>.simpleSongCoverOptions(
song: Song
): BaseRequestOptions<*> {
return baseRequestOptions.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
): RequestBuilder<T> {
return diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.signature(createSignature(song))
}
@JvmStatic
@GlideOption
fun albumCoverOptions(
baseRequestOptions: BaseRequestOptions<*>,
fun <T> RequestBuilder<T>.albumCoverOptions(
song: Song
): BaseRequestOptions<*> {
return baseRequestOptions.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
): RequestBuilder<T> {
return diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(ContextCompat.getDrawable(getContext(), DEFAULT_ALBUM_IMAGE))
.placeholder(ContextCompat.getDrawable(getContext(), DEFAULT_ALBUM_IMAGE))
.signature(createSignature(song))
}
@JvmStatic
@GlideOption
fun userProfileOptions(
baseRequestOptions: BaseRequestOptions<*>,
fun <T> RequestBuilder<T>.userProfileOptions(
file: File,
context: Context
): BaseRequestOptions<*> {
return baseRequestOptions.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
): RequestBuilder<T> {
return diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.error(getErrorUserProfile(context))
.signature(createSignature(file))
}
@JvmStatic
@GlideOption
fun profileBannerOptions(
baseRequestOptions: BaseRequestOptions<*>,
fun <T> RequestBuilder<T>.profileBannerOptions(
file: File
): BaseRequestOptions<*> {
return baseRequestOptions.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
): RequestBuilder<T> {
return diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
.placeholder(DEFAULT_ERROR_IMAGE_BANNER)
.error(DEFAULT_ERROR_IMAGE_BANNER)
.signature(createSignature(file))
}
@JvmStatic
@GlideOption
fun playlistOptions(
baseRequestOptions: BaseRequestOptions<*>
): BaseRequestOptions<*> {
return baseRequestOptions.diskCacheStrategy(DEFAULT_DISK_CACHE_STRATEGY)
fun <T> RequestBuilder<T>.playlistOptions(): RequestBuilder<T> {
return diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.placeholder(getDrawable(DEFAULT_ALBUM_IMAGE))
.error(getDrawable(DEFAULT_ALBUM_IMAGE))
}
@ -223,7 +195,7 @@ object RetroGlideExtension {
}
// https://github.com/bumptech/glide/issues/527#issuecomment-148840717
fun GlideRequest<Drawable>.crossfadeListener(): GlideRequest<Drawable> {
fun RequestBuilder<Drawable>.crossfadeListener(): RequestBuilder<Drawable> {
return listener(object : RequestListener<Drawable> {
override fun onLoadFailed(
e: GlideException?,

View file

@ -11,21 +11,20 @@ class PlaylistPreview(val playlistWithSongs: PlaylistWithSongs) {
val songs: List<Song> get() = playlistWithSongs.songs.toSongs()
override fun equals(other: Any?): Boolean {
if (other is PlaylistPreview) {
if (other.playlistEntity.playListId != playlistEntity.playListId) {
return false
}
if (other.songs.size != songs.size) {
return false
}
return true
}
return false
println("Glide equals $this $other")
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as PlaylistPreview
if (other.playlistEntity.playListId != playlistEntity.playListId) return false
if (other.songs.size != songs.size) return false
return true
}
override fun hashCode(): Int {
var result = playlistEntity.playListId.hashCode()
result = 31 * result + playlistWithSongs.songs.size
println("Glide $result")
return result
}
}

View file

@ -17,7 +17,7 @@ class PlaylistPreviewFetcher(val context: Context, private val playlistPreview:
val bitmap =
AutoGeneratedPlaylistBitmap.getBitmap(
context,
playlistPreview.songs.shuffled()
playlistPreview.songs
)
callback.onDataReady(bitmap)
} catch (e: Exception) {

View file

@ -115,13 +115,15 @@ object MusicPlayerRemote : KoinComponent {
val realActivity = (context as Activity).parent ?: context
val contextWrapper = ContextWrapper(realActivity)
val intent = Intent(contextWrapper, MusicService::class.java)
// https://issuetracker.google.com/issues/76112072#comment184
// Workaround for ForegroundServiceDidNotStartInTimeException
try {
contextWrapper.startService(intent)
} catch (ignored: IllegalStateException) {
runCatching {
ContextCompat.startForegroundService(context, intent)
}
context.startService(intent)
} catch (e: Exception) {
ContextCompat.startForegroundService(context, intent)
}
val binder = ServiceBinder(callback)
if (contextWrapper.bindService(
@ -416,7 +418,7 @@ object MusicPlayerRemote : KoinComponent {
}
}
}
if (songs == null || songs.isEmpty()) {
if (songs.isNullOrEmpty()) {
var songFile: File? = null
if (uri.authority != null && uri.authority == "com.android.externalstorage.documents") {
val path = uri.path?.split(":".toRegex(), 2)?.get(1)
@ -436,7 +438,7 @@ object MusicPlayerRemote : KoinComponent {
songs = songRepository.songsByFilePath(songFile.absolutePath, true)
}
}
if (songs != null && songs.isNotEmpty()) {
if (!songs.isNullOrEmpty()) {
openQueue(songs, 0, true)
} else {
try {

View file

@ -43,7 +43,7 @@ class WallpaperAccentManager(val context: Context) {
.getWallpaperColors(WallpaperManager.FLAG_SYSTEM)
if (colors != null) {
val primaryColor = colors.primaryColor.toArgb()
ThemeStore.editTheme(context).wallpaperColor(context, primaryColor).commit()
ThemeStore.editTheme(context).wallpaperColor(context, primaryColor).commit()
}
}
}

View file

@ -16,7 +16,7 @@ package code.name.monkey.retromusic.repository
import android.content.Context
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.map
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.db.*
import code.name.monkey.retromusic.fragments.search.Filter
@ -99,6 +99,7 @@ interface Repository {
suspend fun isSongFavorite(songId: Long): Boolean
fun getSongByGenre(genreId: Long): Song
fun checkPlaylistExists(playListId: Long): LiveData<Boolean>
fun getPlaylist(playlistId: Long): LiveData<PlaylistWithSongs>
}
class RealRepository(
@ -223,6 +224,8 @@ class RealRepository(
override suspend fun fetchPlaylistWithSongs(): List<PlaylistWithSongs> =
roomRepository.playlistWithSongs()
override fun getPlaylist(playlistId: Long): LiveData<PlaylistWithSongs> = roomRepository.getPlaylist(playlistId)
override suspend fun playlistSongs(playlistWithSongs: PlaylistWithSongs): List<Song> =
playlistWithSongs.songs.map {
it.toSong()
@ -305,7 +308,7 @@ class RealRepository(
roomRepository.playCountSongs()
override fun observableHistorySongs(): LiveData<List<Song>> =
Transformations.map(roomRepository.observableHistorySongs()) {
roomRepository.observableHistorySongs().map {
it.fromHistoryToSongs()
}

View file

@ -44,6 +44,7 @@ interface RoomRepository {
suspend fun deleteSongs(songs: List<Song>)
suspend fun isSongFavorite(context: Context, songId: Long): Boolean
fun checkPlaylistExists(playListId: Long): LiveData<Boolean>
fun getPlaylist(playlistId: Long): LiveData<PlaylistWithSongs>
}
class RealRoomRepository(
@ -81,6 +82,9 @@ class RealRoomRepository(
}
}
@WorkerThread
override fun getPlaylist(playlistId: Long): LiveData<PlaylistWithSongs> = playlistDao.getPlaylist(playlistId)
@WorkerThread
override suspend fun insertSongs(songs: List<SongEntity>) {

View file

@ -93,6 +93,7 @@ class CrossFadePlayer(context: Context) : LocalPlayback(context) {
}
override fun seek(whereto: Int): Int {
endFade()
getNextPlayer()?.stop()
return try {
getCurrentPlayer()?.seekTo(whereto)
@ -235,6 +236,11 @@ class CrossFadePlayer(context: Context) : LocalPlayback(context) {
crossFadeAnimator?.start()
}
private fun endFade() {
crossFadeAnimator?.end()
crossFadeAnimator = null
}
private fun cancelFade() {
crossFadeAnimator?.cancel()
crossFadeAnimator = null

View file

@ -26,6 +26,7 @@ import android.util.Log
import android.view.KeyEvent
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService
import androidx.core.os.BundleCompat
import androidx.media.session.MediaButtonReceiver
import code.name.monkey.retromusic.BuildConfig
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_PAUSE
@ -91,7 +92,7 @@ class MediaButtonIntentReceiver : MediaButtonReceiver() {
println("Intent Action: ${intent.action}")
val intentAction = intent.action
if (Intent.ACTION_MEDIA_BUTTON == intentAction) {
val event = intent.getParcelableExtra<KeyEvent>(Intent.EXTRA_KEY_EVENT)
val event = intent.extras?.let { BundleCompat.getParcelable(it, Intent.EXTRA_KEY_EVENT, KeyEvent::class.java) }
?: return false
val keycode = event.keyCode
@ -106,6 +107,7 @@ class MediaButtonIntentReceiver : MediaButtonReceiver() {
KeyEvent.KEYCODE_MEDIA_STOP -> command = ACTION_STOP
KeyEvent.KEYCODE_HEADSETHOOK, KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE -> command =
ACTION_TOGGLE_PAUSE
KeyEvent.KEYCODE_MEDIA_NEXT -> command = ACTION_SKIP
KeyEvent.KEYCODE_MEDIA_PREVIOUS -> command = ACTION_REWIND
KeyEvent.KEYCODE_MEDIA_PAUSE -> command = ACTION_PAUSE
@ -155,14 +157,8 @@ class MediaButtonIntentReceiver : MediaButtonReceiver() {
val intent = Intent(context, MusicService::class.java)
intent.action = command
try {
// IMPORTANT NOTE: (kind of a hack)
// on Android O and above the following crashes when the app is not running
// there is no good way to check whether the app is running so we catch the exception
// we do not always want to use startForegroundService() because then one gets an ANR
// if no notification is displayed via startForeground()
// according to Play analytics this happens a lot, I suppose for example if command = PAUSE
context.startService(intent)
} catch (ignored: IllegalStateException) {
} catch (e: Exception) {
ContextCompat.startForegroundService(context, intent)
}
}

View file

@ -37,8 +37,11 @@ import android.support.v4.media.session.MediaSessionCompat
import android.support.v4.media.session.PlaybackStateCompat
import android.util.Log
import android.widget.Toast
import androidx.core.app.ServiceCompat
import androidx.core.content.edit
import androidx.core.content.getSystemService
import androidx.core.os.BundleCompat
import androidx.core.os.ParcelCompat
import androidx.media.MediaBrowserServiceCompat
import androidx.preference.PreferenceManager
import code.name.monkey.appthemehelper.util.VersionUtils
@ -47,12 +50,14 @@ import code.name.monkey.retromusic.activities.LockScreenActivity
import code.name.monkey.retromusic.appwidgets.*
import code.name.monkey.retromusic.auto.AutoMediaIDHelper
import code.name.monkey.retromusic.auto.AutoMusicProvider
import code.name.monkey.retromusic.extensions.extra
import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.extensions.toMediaSessionQueue
import code.name.monkey.retromusic.extensions.uri
import code.name.monkey.retromusic.glide.BlurTransformation
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension.getDefaultTransition
import code.name.monkey.retromusic.glide.RetroGlideExtension.getSongModel
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.helper.ShuffleHelper.makeShuffleList
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.Song.Companion.emptySong
@ -82,6 +87,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil.registerOnSharedPreferenc
import code.name.monkey.retromusic.util.PreferenceUtil.unregisterOnSharedPreferenceChangedListener
import code.name.monkey.retromusic.volume.AudioVolumeObserver
import code.name.monkey.retromusic.volume.OnAudioVolumeChangedListener
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
@ -134,21 +140,27 @@ class MusicService : MediaBrowserServiceCompat(),
AppWidgetClassic.NAME -> {
appWidgetClassic.performUpdate(this@MusicService, ids)
}
AppWidgetSmall.NAME -> {
appWidgetSmall.performUpdate(this@MusicService, ids)
}
AppWidgetBig.NAME -> {
appWidgetBig.performUpdate(this@MusicService, ids)
}
AppWidgetCard.NAME -> {
appWidgetCard.performUpdate(this@MusicService, ids)
}
AppWidgetText.NAME -> {
appWidgetText.performUpdate(this@MusicService, ids)
}
AppWidgetMD3.NAME -> {
appWidgetMd3.performUpdate(this@MusicService, ids)
}
AppWidgetCircle.NAME -> {
appWidgetCircle.performUpdate(this@MusicService, ids)
}
@ -412,6 +424,7 @@ class MusicService : MediaBrowserServiceCompat(),
REPEAT_MODE_ALL -> if (isLastTrack) {
position = 0
}
REPEAT_MODE_THIS -> if (force) {
if (isLastTrack) {
position = 0
@ -419,9 +432,11 @@ class MusicService : MediaBrowserServiceCompat(),
} else {
position -= 1
}
REPEAT_MODE_NONE -> if (isLastTrack) {
position -= 1
}
else -> if (isLastTrack) {
position -= 1
}
@ -447,6 +462,7 @@ class MusicService : MediaBrowserServiceCompat(),
REPEAT_MODE_ALL -> if (newPosition < 0) {
newPosition = playingQueue.size - 1
}
REPEAT_MODE_THIS -> if (force) {
if (newPosition < 0) {
newPosition = playingQueue.size - 1
@ -454,9 +470,11 @@ class MusicService : MediaBrowserServiceCompat(),
} else {
newPosition = getPosition()
}
REPEAT_MODE_NONE -> if (newPosition < 0) {
newPosition = 0
}
else -> if (newPosition < 0) {
newPosition = 0
}
@ -486,6 +504,7 @@ class MusicService : MediaBrowserServiceCompat(),
makeShuffleList(playingQueue, getPosition())
position = 0
}
SHUFFLE_MODE_NONE -> {
this.shuffleMode = shuffleMode
val currentSongId = Objects.requireNonNull(currentSong).id
@ -553,9 +572,11 @@ class MusicService : MediaBrowserServiceCompat(),
currentPosition in to until from -> {
position = currentPosition + 1
}
currentPosition in (from + 1)..to -> {
position = currentPosition - 1
}
from == currentPosition -> {
position = to
}
@ -617,6 +638,7 @@ class MusicService : MediaBrowserServiceCompat(),
updateMediaSessionPlaybackState()
playbackManager.setPlaybackSpeedPitch(playbackSpeed, playbackPitch)
}
CROSS_FADE_DURATION -> {
val progress = songProgressMillis
val wasPlaying = isPlaying
@ -627,6 +649,7 @@ class MusicService : MediaBrowserServiceCompat(),
playbackManager.setCrossFadeDuration(crossFadeDuration)
}
}
ALBUM_ART_ON_LOCK_SCREEN, BLURRED_ALBUM_ART -> updateMediaSessionMetaData(::updateMediaSessionPlaybackState)
COLORED_NOTIFICATION -> {
playingNotification?.updateMetadata(currentSong) {
@ -634,6 +657,7 @@ class MusicService : MediaBrowserServiceCompat(),
startForegroundOrNotify()
}
}
CLASSIC_NOTIFICATION -> {
updateNotification()
playingNotification?.updateMetadata(currentSong) {
@ -641,6 +665,7 @@ class MusicService : MediaBrowserServiceCompat(),
startForegroundOrNotify()
}
}
TOGGLE_HEADSET -> registerHeadsetEvents()
}
}
@ -655,6 +680,7 @@ class MusicService : MediaBrowserServiceCompat(),
} else {
play()
}
ACTION_PAUSE -> pause()
ACTION_PLAY -> play()
ACTION_PLAY_PLAYLIST -> playFromPlaylist(intent)
@ -664,6 +690,7 @@ class MusicService : MediaBrowserServiceCompat(),
pendingQuit = false
quit()
}
ACTION_PENDING_QUIT -> pendingQuit = true
TOGGLE_FAVORITE -> toggleFavorite()
}
@ -727,7 +754,7 @@ class MusicService : MediaBrowserServiceCompat(),
startPosition: Int,
startPlaying: Boolean,
) {
if (playingQueue != null && playingQueue.isNotEmpty()
if (!playingQueue.isNullOrEmpty()
&& startPosition >= 0 && startPosition < playingQueue.size
) {
// it is important to copy the playing queue here first as we might add/remove songs later
@ -829,7 +856,7 @@ class MusicService : MediaBrowserServiceCompat(),
fun quit() {
pause()
stopForeground(true)
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
isForeground = false
notificationManager?.cancel(PlayingNotification.NOTIFICATION_ID)
@ -1023,7 +1050,7 @@ class MusicService : MediaBrowserServiceCompat(),
if (isAlbumArtOnLockScreen) {
// val screenSize: Point = RetroUtil.getScreenSize(this)
val request = GlideApp.with(this)
val request = Glide.with(this)
.asBitmap()
.songCoverOptions(song)
.load(getSongModel(song))
@ -1078,12 +1105,14 @@ class MusicService : MediaBrowserServiceCompat(),
playingNotification?.setPlaying(isPlaying)
startForegroundOrNotify()
}
FAVORITE_STATE_CHANGED -> {
isCurrentFavorite { isFavorite ->
playingNotification?.updateFavorite(isFavorite)
startForegroundOrNotify()
}
}
META_CHANGED -> {
playingNotification?.updateMetadata(currentSong) { startForegroundOrNotify() }
isCurrentFavorite { isFavorite ->
@ -1107,6 +1136,7 @@ class MusicService : MediaBrowserServiceCompat(),
storage.saveSong(currentSong)
}
}
QUEUE_CHANGED -> {
mediaSession?.setQueueTitle(getString(R.string.now_playing_queue))
mediaSession?.setQueue(playingQueue.toMediaSessionQueue())
@ -1128,7 +1158,7 @@ class MusicService : MediaBrowserServiceCompat(),
// We can't call stopForeground(false) on A12 though, which may result in crashes
// when we call startForeground after that e.g. when Alarm goes off,
if (!VersionUtils.hasS()) {
stopForeground(false)
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_DETACH)
isForeground = false
}
}
@ -1156,7 +1186,7 @@ class MusicService : MediaBrowserServiceCompat(),
}
private fun stopForegroundAndNotification() {
stopForeground(true)
ServiceCompat.stopForeground(this, ServiceCompat.STOP_FOREGROUND_REMOVE)
notificationManager?.cancel(PlayingNotification.NOTIFICATION_ID)
isForeground = false
}
@ -1198,7 +1228,13 @@ class MusicService : MediaBrowserServiceCompat(),
}
private fun playFromPlaylist(intent: Intent) {
val playlist: AbsSmartPlaylist? = intent.getParcelableExtra(INTENT_EXTRA_PLAYLIST)
val playlist: AbsSmartPlaylist? = intent.extras?.let {
BundleCompat.getParcelable(
it,
INTENT_EXTRA_PLAYLIST,
AbsSmartPlaylist::class.java
)
}
val shuffleMode = intent.getIntExtra(INTENT_EXTRA_SHUFFLE_MODE, getShuffleMode())
if (playlist != null) {
val playlistSongs = playlist.songs()
@ -1355,7 +1391,7 @@ class MusicService : MediaBrowserServiceCompat(),
const val INTENT_EXTRA_PLAYLIST = RETRO_MUSIC_PACKAGE_NAME + "intentextra.playlist"
const val INTENT_EXTRA_SHUFFLE_MODE =
"$RETRO_MUSIC_PACKAGE_NAME.intentextra.shufflemode"
const val APP_WIDGET_UPDATE = "$RETRO_MUSIC_PACKAGE_NAME.appreciate"
const val APP_WIDGET_UPDATE = "$RETRO_MUSIC_PACKAGE_NAME.appwidgetupdate"
const val EXTRA_APP_WIDGET_NAME = RETRO_MUSIC_PACKAGE_NAME + "app_widget_name"
// Do not change these three strings as it will break support with other apps (e.g. last.fm

View file

@ -36,8 +36,9 @@ import code.name.monkey.retromusic.extensions.getTintedDrawable
import code.name.monkey.retromusic.extensions.isColorLight
import code.name.monkey.retromusic.extensions.isSystemDarkModeEnabled
import code.name.monkey.retromusic.extensions.toBitmap
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.asBitmapPalette
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService
@ -47,6 +48,7 @@ import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_SKIP
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_PAUSE
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
@ -105,7 +107,9 @@ class PlayingNotificationClassic(
setOngoing(true)
val bigNotificationImageSize = context.resources
.getDimensionPixelSize(R.dimen.notification_big_image_size)
GlideApp.with(context).asBitmapPalette().songCoverOptions(song)
Glide.with(context)
.asBitmapPalette()
.songCoverOptions(song)
.load(RetroGlideExtension.getSongModel(song))
.centerCrop()
.into(object : CustomTarget<BitmapPaletteWrapper>(
@ -124,14 +128,22 @@ class PlayingNotificationClassic(
super.onLoadFailed(errorDrawable)
update(
null,
resolveColor(context, com.google.android.material.R.attr.colorSurface, Color.WHITE)
resolveColor(
context,
com.google.android.material.R.attr.colorSurface,
Color.WHITE
)
)
}
override fun onLoadCleared(placeholder: Drawable?) {
update(
null,
resolveColor(context, com.google.android.material.R.attr.colorSurface, Color.WHITE)
resolveColor(
context,
com.google.android.material.R.attr.colorSurface,
Color.WHITE
)
)
}
@ -157,7 +169,11 @@ class PlayingNotificationClassic(
if (!VersionUtils.hasS()) {
if (!PreferenceUtil.isColoredNotification) {
bgColorFinal =
resolveColor(context, com.google.android.material.R.attr.colorSurface, Color.WHITE)
resolveColor(
context,
com.google.android.material.R.attr.colorSurface,
Color.WHITE
)
}
setBackgroundColor(bgColorFinal)
setNotificationContent(ColorUtil.isColorLight(bgColorFinal))

View file

@ -28,8 +28,8 @@ import androidx.media.app.NotificationCompat.MediaStyle
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.MainActivity
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.glide.RetroGlideExtension
import code.name.monkey.retromusic.glide.RetroGlideExtension.songCoverOptions
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_QUIT
@ -38,6 +38,7 @@ import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_SKIP
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_PAUSE
import code.name.monkey.retromusic.service.MusicService.Companion.TOGGLE_FAVORITE
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
@ -116,7 +117,7 @@ class PlayingNotificationImpl24(
setSubText(song.albumName)
val bigNotificationImageSize = context.resources
.getDimensionPixelSize(R.dimen.notification_big_image_size)
GlideApp.with(context)
Glide.with(context)
.asBitmap()
.songCoverOptions(song)
.load(RetroGlideExtension.getSongModel(song))

View file

@ -4,10 +4,10 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MergedImageUtils.joinImages
import code.name.monkey.retromusic.util.MusicUtil.getMediaStoreAlbumCoverUri
import com.bumptech.glide.Glide
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
object AutoGeneratedPlaylistBitmap {
@ -31,7 +31,7 @@ object AutoGeneratedPlaylistBitmap {
private fun getBitmapWithAlbumId(context: Context, id: Long): Bitmap? {
return try {
GlideApp.with(context)
Glide.with(context)
.asBitmap()
.transform(RoundedCorners(20))
.load(getMediaStoreAlbumCoverUri(id))

View file

@ -24,14 +24,14 @@ import androidx.core.content.edit
import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.model.Artist
import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.withContext
import java.io.File
import java.io.IOException
import java.util.*
import java.util.Locale
class CustomArtistImageUtil private constructor(context: Context) {
@ -45,7 +45,7 @@ class CustomArtistImageUtil private constructor(context: Context) {
val context = App.getContext()
withContext(IO) {
runCatching {
GlideApp.with(context)
Glide.with(context)
.asBitmap()
.load(uri)
.diskCacheStrategy(DiskCacheStrategy.NONE)

View file

@ -11,6 +11,7 @@ import code.name.monkey.retromusic.databinding.SimpleAppbarLayoutBinding
import code.name.monkey.retromusic.util.PreferenceUtil
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.LayoutParams.SCROLL_FLAG_NO_SCROLL
import com.google.android.material.appbar.MaterialToolbar
import com.google.android.material.shape.MaterialShapeDrawable
import dev.chrisbanes.insetter.applyInsetter
@ -52,24 +53,24 @@ class TopAppBarLayout @JvmOverloads constructor(
}
}
val toolbar: Toolbar
val toolbar: MaterialToolbar
get() = if (mode == AppBarMode.COLLAPSING) {
collapsingAppbarBinding?.toolbar!!
} else {
simpleAppbarBinding?.toolbar!!
}
var title: String
var title: CharSequence
get() = if (mode == AppBarMode.COLLAPSING) {
collapsingAppbarBinding?.collapsingToolbarLayout?.title.toString()
} else {
simpleAppbarBinding?.appNameText?.text.toString()
simpleAppbarBinding?.toolbar?.title.toString()
}
set(value) {
if (mode == AppBarMode.COLLAPSING) {
collapsingAppbarBinding?.collapsingToolbarLayout?.title = value
} else {
simpleAppbarBinding?.appNameText?.text = value
simpleAppbarBinding?.toolbar?.title = value
}
}

View file

@ -7,24 +7,17 @@
android:fitsSystemWindows="true"
android:orientation="vertical"
android:transitionGroup="true"
android:transitionName="@string/transition_album_art"
tools:ignore="UnusedAttribute">
android:transitionName="@string/transition_album_art">
<FrameLayout
android:id="@+id/toolbar_container"
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:navigationIcon="@drawable/ic_arrow_back" />
</FrameLayout>
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_arrow_back" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/albumCoverContainer"
@ -37,7 +30,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar_container">
app:layout_constraintTop_toBottomOf="@id/toolbar">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image"
@ -61,7 +54,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/albumCoverContainer"
app:layout_constraintTop_toBottomOf="@id/toolbar_container">
app:layout_constraintTop_toBottomOf="@id/toolbar">
<LinearLayout
android:layout_width="match_parent"

View file

@ -5,24 +5,17 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical"
tools:ignore="UnusedAttribute">
android:orientation="vertical">
<FrameLayout
android:id="@+id/toolbar_container"
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
style="@style/Toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:navigationIcon="@drawable/ic_arrow_back" />
</FrameLayout>
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="@drawable/ic_arrow_back" />
<com.google.android.material.card.MaterialCardView
android:id="@+id/artistCoverContainer"
@ -36,7 +29,7 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/toolbar_container">
app:layout_constraintTop_toBottomOf="@id/toolbar">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/image"
@ -60,7 +53,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/artistCoverContainer"
app:layout_constraintTop_toBottomOf="@id/toolbar_container">
app:layout_constraintTop_toBottomOf="@id/toolbar">
<LinearLayout
android:layout_width="match_parent"

View file

@ -18,42 +18,12 @@
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<com.google.android.material.appbar.AppBarLayout
<code.name.monkey.retromusic.views.TopAppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:liftOnScroll="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:navigationIcon="@drawable/ic_search"
app:popupTheme="?attr/toolbarPopupTheme"
app:title="@null"
tools:ignore="UnusedAttribute">
<com.google.android.material.textview.MaterialTextView
android:id="@+id/appNameText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textAppearance="@style/TextViewHeadline6"
android:textStyle="bold" />
</androidx.appcompat.widget.Toolbar>
<ViewStub
android:id="@+id/cab_stub"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height" />
</FrameLayout>
</com.google.android.material.appbar.AppBarLayout>
app:liftOnScroll="true" />
<androidx.core.widget.NestedScrollView
android:id="@+id/container"

View file

@ -22,9 +22,4 @@
app:navigationIcon="@drawable/ic_search"
app:titleTextAppearance="@style/ToolbarTextAppearanceNormal"
tools:title="@string/songs" />
<FrameLayout
android:id="@+id/toolbar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.appbar.CollapsingToolbarLayout>

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