Merge branch 'RetroMusicPlayer:dev' into feat/audio_focus_2
This commit is contained in:
commit
51f772247a
305 changed files with 2587 additions and 5938 deletions
|
@ -5,17 +5,17 @@ apply plugin: "androidx.navigation.safeargs.kotlin"
|
|||
apply plugin: 'kotlin-parcelize'
|
||||
|
||||
android {
|
||||
compileSdk 31
|
||||
compileSdk 32
|
||||
|
||||
defaultConfig {
|
||||
minSdk 21
|
||||
targetSdk 31
|
||||
targetSdk 32
|
||||
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
|
||||
applicationId "code.name.monkey.retromusic"
|
||||
versionCode 10573
|
||||
versionName '5.8.0'
|
||||
versionCode 10576
|
||||
versionName '5.8.3'
|
||||
|
||||
buildConfigField("String", "GOOGLE_PLAY_LICENSING_KEY", "\"${getProperty(getProperties('../public.properties'), 'GOOGLE_PLAY_LICENSE_KEY')}\"")
|
||||
}
|
||||
|
@ -55,8 +55,6 @@ android {
|
|||
disable 'MissingTranslation', 'InvalidPackage'
|
||||
}
|
||||
compileOptions {
|
||||
coreLibraryDesugaringEnabled true
|
||||
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
@ -99,7 +97,7 @@ dependencies {
|
|||
implementation 'androidx.palette:palette-ktx:1.0.0'
|
||||
|
||||
//Cast Dependencies
|
||||
implementation 'androidx.mediarouter:mediarouter:1.3.0-rc01'
|
||||
implementation 'androidx.mediarouter:mediarouter:1.3.0'
|
||||
implementation 'com.google.android.gms:play-services-cast-framework:21.0.1'
|
||||
//WebServer by NanoHttpd
|
||||
implementation "org.nanohttpd:nanohttpd:2.3.1"
|
||||
|
@ -113,7 +111,7 @@ dependencies {
|
|||
implementation "androidx.room:room-ktx:$room_version"
|
||||
kapt "androidx.room:room-compiler:$room_version"
|
||||
|
||||
def lifecycle_version = "2.4.1"
|
||||
def lifecycle_version = "2.5.0-beta01"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
|
||||
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
|
||||
|
@ -126,19 +124,18 @@ dependencies {
|
|||
def retrofit_version = '2.9.0'
|
||||
implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
|
||||
implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.6'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.7'
|
||||
|
||||
def material_dialog_version = "3.3.0"
|
||||
implementation "com.afollestad.material-dialogs:core:$material_dialog_version"
|
||||
implementation "com.afollestad.material-dialogs:input:$material_dialog_version"
|
||||
implementation "com.afollestad.material-dialogs:color:$material_dialog_version"
|
||||
implementation "com.afollestad.material-dialogs:bottomsheets:$material_dialog_version"
|
||||
|
||||
implementation 'com.afollestad:material-cab:2.0.1'
|
||||
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||
|
||||
def kotlin_coroutines_version = '1.6.0'
|
||||
def kotlin_coroutines_version = '1.6.1'
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
|
||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
|
||||
|
||||
|
@ -151,8 +148,6 @@ dependencies {
|
|||
kapt "com.github.bumptech.glide:compiler:$glide_version"
|
||||
implementation "com.github.bumptech.glide:okhttp3-integration:$glide_version"
|
||||
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
|
||||
implementation 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:1.0.0'
|
||||
|
||||
implementation 'com.github.bosphere.android-fadingedgelayout:fadingedgelayout:1.0.0'
|
||||
|
@ -168,9 +163,8 @@ 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.7'
|
||||
implementation 'me.zhanghai.android.fastscroll:library:1.1.8'
|
||||
implementation 'cat.ereza:customactivityoncrash:2.3.0'
|
||||
implementation 'me.tankery.lib:circularSeekBar:1.3.2'
|
||||
debugImplementation 'com.github.amitshekhariitbhu:Android-Debug-Database:1.0.6'
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1'
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.9.1'
|
||||
}
|
|
@ -19,7 +19,7 @@
|
|||
tools:ignore="ProtectedPermissions" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="com.android.vending.BILLING" />
|
||||
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
|
@ -116,7 +116,6 @@
|
|||
<activity android:name=".activities.SupportDevelopmentActivity" />
|
||||
<activity android:name=".activities.LicenseActivity" />
|
||||
<activity android:name=".activities.PurchaseActivity" />
|
||||
<activity android:name=".activities.WhatsNewActivity" />
|
||||
<activity android:name=".activities.bugreport.BugReportActivity" />
|
||||
<activity android:name=".activities.ShareInstagramStory" />
|
||||
<activity android:name=".activities.DriveModeActivity" />
|
||||
|
@ -190,7 +189,6 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
|
||||
<provider
|
||||
android:name=".misc.GenericFileProvider"
|
||||
android:authorities="${applicationId}.provider"
|
||||
|
|
|
@ -62,6 +62,22 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<div>
|
||||
<h5>May 07, 2022</h5>
|
||||
<h2>v5.8.3</h2>
|
||||
<h3>What's New</h3>
|
||||
<ul>
|
||||
<li>Swipe down to dismiss Mini player</li>
|
||||
<li>Add support for Just Black with Material You</li>
|
||||
</ul>
|
||||
<h3>Fixed</h3>
|
||||
<ul>
|
||||
<li>Fixed sharing of files from SD Card</li>
|
||||
<li>Fix ChromeCast crash and bugs</li>
|
||||
<li>Fix Audio Crossfade</li>
|
||||
<li>Tried to fix incorrect song data in notification</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h5>April 8, 2022</h5>
|
||||
<h2>v5.8.0</h2>
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
package code.name.monkey.retromusic
|
||||
|
||||
import android.app.Application
|
||||
import android.widget.Toast
|
||||
import cat.ereza.customactivityoncrash.config.CaocConfig
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||
import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID
|
||||
import code.name.monkey.retromusic.activities.ErrorActivity
|
||||
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
|
||||
import code.name.monkey.retromusic.extensions.showToast
|
||||
import code.name.monkey.retromusic.helper.WallpaperAccentManager
|
||||
import com.anjlab.android.iab.v3.BillingProcessor
|
||||
import com.anjlab.android.iab.v3.PurchaseInfo
|
||||
|
@ -60,11 +60,7 @@ class App : Application() {
|
|||
override fun onProductPurchased(productId: String, details: PurchaseInfo?) {}
|
||||
|
||||
override fun onPurchaseHistoryRestored() {
|
||||
Toast.makeText(
|
||||
this@App,
|
||||
R.string.restored_previous_purchase_please_restart,
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
showToast(R.string.restored_previous_purchase_please_restart)
|
||||
}
|
||||
|
||||
override fun onBillingError(errorCode: Int, error: Throwable?) {}
|
||||
|
|
|
@ -37,6 +37,8 @@ object Constants {
|
|||
const val IS_MUSIC =
|
||||
MediaStore.Audio.AudioColumns.IS_MUSIC + "=1" + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''"
|
||||
|
||||
const val DATA = "_data"
|
||||
|
||||
@Suppress("Deprecation")
|
||||
val baseProjection = arrayOf(
|
||||
BaseColumns._ID, // 0
|
||||
|
@ -44,7 +46,7 @@ object Constants {
|
|||
MediaStore.Audio.AudioColumns.TRACK, // 2
|
||||
MediaStore.Audio.AudioColumns.YEAR, // 3
|
||||
MediaStore.Audio.AudioColumns.DURATION, // 4
|
||||
MediaStore.Audio.AudioColumns.DATA, // 5
|
||||
DATA, // 5
|
||||
MediaStore.Audio.AudioColumns.DATE_MODIFIED, // 6
|
||||
MediaStore.Audio.AudioColumns.ALBUM_ID, // 7
|
||||
MediaStore.Audio.AudioColumns.ALBUM, // 8
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
package code.name.monkey.retromusic;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.os.LocaleList;
|
||||
|
||||
import com.google.android.gms.common.annotation.KeepName;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils;
|
||||
|
||||
public class LanguageContextWrapper extends ContextWrapper {
|
||||
|
||||
public LanguageContextWrapper(Context base) {
|
||||
super(base);
|
||||
}
|
||||
|
||||
@KeepName
|
||||
public static LanguageContextWrapper wrap(Context context, Locale newLocale) {
|
||||
Resources res = context.getResources();
|
||||
Configuration configuration = res.getConfiguration();
|
||||
|
||||
if (VersionUtils.INSTANCE.hasNougatMR()) {
|
||||
configuration.setLocale(newLocale);
|
||||
|
||||
LocaleList localeList = new LocaleList(newLocale);
|
||||
LocaleList.setDefault(localeList);
|
||||
configuration.setLocales(localeList);
|
||||
} else {
|
||||
configuration.setLocale(newLocale);
|
||||
}
|
||||
context = context.createConfigurationContext(configuration);
|
||||
return new LanguageContextWrapper(context);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package code.name.monkey.retromusic
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.os.LocaleList
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils.hasNougatMR
|
||||
import com.google.android.gms.common.annotation.KeepName
|
||||
import java.util.*
|
||||
|
||||
class LanguageContextWrapper(base: Context?) : ContextWrapper(base) {
|
||||
companion object {
|
||||
@KeepName
|
||||
fun wrap(context: Context?, newLocale: Locale?): LanguageContextWrapper {
|
||||
if (context == null) return LanguageContextWrapper(context)
|
||||
val configuration = context.resources.configuration
|
||||
if (hasNougatMR()) {
|
||||
configuration.setLocale(newLocale)
|
||||
val localeList = LocaleList(newLocale)
|
||||
LocaleList.setDefault(localeList)
|
||||
configuration.setLocales(localeList)
|
||||
} else {
|
||||
configuration.setLocale(newLocale)
|
||||
}
|
||||
return LanguageContextWrapper(context.createConfigurationContext(configuration))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import androidx.room.Room
|
|||
import androidx.room.RoomDatabase
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import code.name.monkey.retromusic.auto.AutoMusicProvider
|
||||
import code.name.monkey.retromusic.cast.RetroWebServer
|
||||
import code.name.monkey.retromusic.db.BlackListStoreDao
|
||||
import code.name.monkey.retromusic.db.BlackListStoreEntity
|
||||
import code.name.monkey.retromusic.db.PlaylistWithSongs
|
||||
|
@ -88,7 +89,8 @@ private val roomModule = module {
|
|||
}
|
||||
private val autoModule = module {
|
||||
single {
|
||||
AutoMusicProvider(androidContext(),
|
||||
AutoMusicProvider(
|
||||
androidContext(),
|
||||
get(),
|
||||
get(),
|
||||
get(),
|
||||
|
@ -102,6 +104,9 @@ private val mainModule = module {
|
|||
single {
|
||||
androidContext().contentResolver
|
||||
}
|
||||
single {
|
||||
RetroWebServer(get())
|
||||
}
|
||||
}
|
||||
private val dataModule = module {
|
||||
single {
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
package code.name.monkey.retromusic;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout;
|
||||
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class RetroBottomSheetBehavior<V extends View> extends BottomSheetBehavior<V> {
|
||||
|
||||
private static final String TAG = "RetroBottomSheetBehavior";
|
||||
|
||||
private boolean allowDragging = true;
|
||||
|
||||
public RetroBottomSheetBehavior() {}
|
||||
|
||||
public RetroBottomSheetBehavior(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public void setAllowDragging(boolean allowDragging) {
|
||||
this.allowDragging = allowDragging;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(
|
||||
@NotNull CoordinatorLayout parent, @NotNull V child, @NotNull MotionEvent event) {
|
||||
if (!allowDragging) {
|
||||
return false;
|
||||
}
|
||||
return super.onInterceptTouchEvent(parent, child, event);
|
||||
}
|
||||
}
|
|
@ -22,11 +22,11 @@ import android.os.Bundle
|
|||
import android.view.animation.LinearInterpolator
|
||||
import android.widget.SeekBar
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
||||
import code.name.monkey.retromusic.databinding.ActivityDriveModeBinding
|
||||
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.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.glide.BlurTransformation
|
||||
|
@ -66,7 +66,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
|
|||
setUpMusicControllers()
|
||||
|
||||
progressViewUpdateHelper = MusicProgressViewUpdateHelper(this)
|
||||
lastPlaybackControlsColor = ThemeStore.accentColor(this)
|
||||
lastPlaybackControlsColor = accentColor()
|
||||
binding.close.setOnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
|
@ -91,7 +91,6 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
|
|||
private fun toggleFavorite(song: Song) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val playlist = repository.favoritePlaylist()
|
||||
if (playlist != null) {
|
||||
val songEntity = song.toSongEntity(playlist.playListId)
|
||||
val isFavorite = repository.isSongFavorite(song.id)
|
||||
if (isFavorite) {
|
||||
|
@ -99,7 +98,6 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
|
|||
} else {
|
||||
repository.insertSongs(listOf(song.toSongEntity(playlist.playListId)))
|
||||
}
|
||||
}
|
||||
sendBroadcast(Intent(MusicService.FAVORITE_STATE_CHANGED))
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +137,6 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
|
|||
}
|
||||
|
||||
private fun setUpPrevNext() {
|
||||
|
||||
binding.nextButton.setOnClickListener { MusicPlayerRemote.playNextSong() }
|
||||
binding.previousButton.setOnClickListener { MusicPlayerRemote.back() }
|
||||
}
|
||||
|
@ -246,7 +243,8 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
|
|||
|
||||
GlideApp.with(this)
|
||||
.load(RetroGlideExtension.getSongModel(song))
|
||||
.songCoverOptions(song).transform(BlurTransformation.Builder(this).build())
|
||||
.songCoverOptions(song)
|
||||
.transform(BlurTransformation.Builder(this).build())
|
||||
.into(binding.image)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,12 +16,12 @@ package code.name.monkey.retromusic.activities
|
|||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil.isWindowBackgroundDark
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil.lightenColor
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
|
||||
import code.name.monkey.retromusic.databinding.ActivityLicenseBinding
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.drawAboveSystemBars
|
||||
import code.name.monkey.retromusic.extensions.surfaceColor
|
||||
import java.io.BufferedReader
|
||||
|
@ -59,11 +59,11 @@ class LicenseActivity : AbsThemeActivity() {
|
|||
"body { background-color: %s; color: %s; }", backgroundColor, contentColor
|
||||
)
|
||||
)
|
||||
.replace("{link-color}", colorToCSS(accentColor(this)))
|
||||
.replace("{link-color}", colorToCSS(accentColor()))
|
||||
.replace(
|
||||
"{link-color-active}",
|
||||
colorToCSS(
|
||||
lightenColor(accentColor(this))
|
||||
lightenColor(accentColor())
|
||||
)
|
||||
)
|
||||
binding.license.loadData(changeLog, "text/html", "UTF-8")
|
||||
|
|
|
@ -35,7 +35,6 @@ import code.name.monkey.retromusic.model.Song
|
|||
import code.name.monkey.retromusic.repository.PlaylistSongsLoader
|
||||
import code.name.monkey.retromusic.service.MusicService
|
||||
import code.name.monkey.retromusic.util.AppRater
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.launch
|
||||
|
@ -62,9 +61,7 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener {
|
|||
if (!hasPermissions()) {
|
||||
findNavController(R.id.fragment_container).navigate(R.id.permissionFragment)
|
||||
}
|
||||
if (BuildConfig.VERSION_CODE > PreferenceUtil.lastVersion && !BuildConfig.DEBUG) {
|
||||
NavigationUtil.gotoWhatNews(this)
|
||||
}
|
||||
WhatsNewFragment.showChangeLog(this)
|
||||
}
|
||||
|
||||
private fun setupNavigationController() {
|
||||
|
@ -179,7 +176,7 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener {
|
|||
handled = true
|
||||
}
|
||||
if (uri != null && uri.toString().isNotEmpty()) {
|
||||
MusicPlayerRemote.playFromUri(uri)
|
||||
MusicPlayerRemote.playFromUri(this@MainActivity, uri)
|
||||
handled = true
|
||||
} else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) {
|
||||
val id = parseLongFromIntent(intent, "playlistId", "playlist")
|
||||
|
|
|
@ -22,17 +22,14 @@ import android.os.Build
|
|||
import android.os.Bundle
|
||||
import android.provider.Settings
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.core.view.isVisible
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||
import code.name.monkey.retromusic.activities.base.AbsMusicServiceActivity
|
||||
import code.name.monkey.retromusic.databinding.ActivityPermissionBinding
|
||||
import code.name.monkey.retromusic.extensions.accentBackgroundColor
|
||||
import code.name.monkey.retromusic.extensions.setStatusBarColorAuto
|
||||
import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
|
||||
import code.name.monkey.retromusic.extensions.show
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.util.RingtoneManager
|
||||
|
||||
class PermissionActivity : AbsMusicServiceActivity() {
|
||||
|
@ -75,32 +72,32 @@ class PermissionActivity : AbsMusicServiceActivity() {
|
|||
}
|
||||
|
||||
private fun setupTitle() {
|
||||
val color = ThemeStore.accentColor(this)
|
||||
val color = accentColor()
|
||||
val hexColor = String.format("#%06X", 0xFFFFFF and color)
|
||||
val appName = "Hello there! <br>Welcome to <b>Retro <span style='color:$hexColor';>Music</span></b>"
|
||||
val appName =
|
||||
"Hello there! <br>Welcome to <b>Retro <span style='color:$hexColor';>Music</span></b>"
|
||||
.parseAsHtml()
|
||||
binding.appNameText.text = appName
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (hasStoragePermission()) {
|
||||
binding.storagePermission.checkImage.isVisible = true
|
||||
binding.storagePermission.checkImage.imageTintList =
|
||||
ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||
ColorStateList.valueOf(accentColor())
|
||||
}
|
||||
if (VersionUtils.hasMarshmallow()) {
|
||||
if (hasAudioPermission()) {
|
||||
binding.audioPermission.checkImage.isVisible = true
|
||||
binding.audioPermission.checkImage.imageTintList =
|
||||
ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||
ColorStateList.valueOf(accentColor())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
private fun hasStoragePermission(): Boolean {
|
||||
return checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
|
||||
return ActivityCompat.checkSelfPermission(this , Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
|
|
|
@ -19,8 +19,6 @@ import android.graphics.Color
|
|||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.MenuItem
|
||||
import android.widget.Toast
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.BuildConfig
|
||||
|
@ -28,8 +26,10 @@ import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||
import code.name.monkey.retromusic.databinding.ActivityProVersionBinding
|
||||
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.extensions.showToast
|
||||
import com.anjlab.android.iab.v3.BillingProcessor
|
||||
import com.anjlab.android.iab.v3.PurchaseInfo
|
||||
|
||||
|
@ -61,12 +61,11 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
|||
billingProcessor.purchase(this@PurchaseActivity, PRO_VERSION_PRODUCT_ID)
|
||||
}
|
||||
binding.bannerContainer.backgroundTintList =
|
||||
ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||
ColorStateList.valueOf(accentColor())
|
||||
}
|
||||
|
||||
private fun restorePurchase() {
|
||||
Toast.makeText(this, R.string.restoring_purchase, Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
showToast(R.string.restoring_purchase)
|
||||
billingProcessor.loadOwnedPurchasesFromGoogleAsync(object :
|
||||
BillingProcessor.IPurchasesResponseListener {
|
||||
override fun onPurchasesSuccess() {
|
||||
|
@ -74,30 +73,22 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
|
|||
}
|
||||
|
||||
override fun onPurchasesError() {
|
||||
Toast.makeText(
|
||||
this@PurchaseActivity,
|
||||
R.string.could_not_restore_purchase,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
showToast(R.string.could_not_restore_purchase)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onProductPurchased(productId: String, details: PurchaseInfo?) {
|
||||
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
|
||||
showToast(R.string.thank_you)
|
||||
setResult(RESULT_OK)
|
||||
}
|
||||
|
||||
override fun onPurchaseHistoryRestored() {
|
||||
if (App.isProVersion()) {
|
||||
Toast.makeText(
|
||||
this,
|
||||
R.string.restored_previous_purchase_please_restart,
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
showToast(R.string.restored_previous_purchase_please_restart)
|
||||
setResult(RESULT_OK)
|
||||
} else {
|
||||
Toast.makeText(this, R.string.no_purchase_found, Toast.LENGTH_SHORT).show()
|
||||
showToast(R.string.no_purchase_found)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,11 @@ import android.provider.MediaStore.Images.Media
|
|||
import android.view.MenuItem
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.drawToBitmap
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||
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
|
||||
|
@ -96,11 +96,11 @@ class ShareInstagramStory : AbsBaseActivity() {
|
|||
binding.shareButton.setTextColor(
|
||||
MaterialValueHelper.getPrimaryTextColor(
|
||||
this,
|
||||
ColorUtil.isColorLight(ThemeStore.accentColor(this))
|
||||
ColorUtil.isColorLight(accentColor())
|
||||
)
|
||||
)
|
||||
binding.shareButton.backgroundTintList =
|
||||
ColorStateList.valueOf(ThemeStore.accentColor(this))
|
||||
ColorStateList.valueOf(accentColor())
|
||||
}
|
||||
|
||||
private fun setColors(colorLight: Boolean, color: Int) {
|
||||
|
|
|
@ -21,12 +21,10 @@ import android.view.LayoutInflater
|
|||
import android.view.MenuItem
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
|
@ -75,8 +73,8 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH
|
|||
setupToolbar()
|
||||
|
||||
billingProcessor = BillingProcessor(this, BuildConfig.GOOGLE_PLAY_LICENSING_KEY, this)
|
||||
TintHelper.setTint(binding.progress, ThemeStore.accentColor(this))
|
||||
binding.donation.setTextColor(ThemeStore.accentColor(this))
|
||||
TintHelper.setTint(binding.progress, accentColor())
|
||||
binding.donation.setTextColor(accentColor())
|
||||
}
|
||||
|
||||
private fun setupToolbar() {
|
||||
|
@ -121,7 +119,7 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH
|
|||
|
||||
override fun onProductPurchased(productId: String, details: PurchaseInfo?) {
|
||||
// loadSkuDetails();
|
||||
Toast.makeText(this, R.string.thank_you, Toast.LENGTH_SHORT).show()
|
||||
showToast(R.string.thank_you)
|
||||
}
|
||||
|
||||
override fun onBillingError(errorCode: Int, error: Throwable?) {
|
||||
|
@ -130,7 +128,7 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH
|
|||
|
||||
override fun onPurchaseHistoryRestored() {
|
||||
// loadSkuDetails();
|
||||
Toast.makeText(this, R.string.restored_previous_purchases, Toast.LENGTH_SHORT).show()
|
||||
showToast(R.string.restored_previous_purchases)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
|
|
@ -4,39 +4,45 @@ import android.content.Context
|
|||
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 androidx.core.content.pm.PackageInfoCompat
|
||||
import androidx.core.widget.NestedScrollView
|
||||
import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil.isWindowBackgroundDark
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil.isColorLight
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil.lightenColor
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper.getPrimaryTextColor
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.BuildConfig
|
||||
import code.name.monkey.retromusic.Constants
|
||||
import code.name.monkey.retromusic.activities.base.AbsThemeActivity
|
||||
import code.name.monkey.retromusic.databinding.ActivityWhatsNewBinding
|
||||
import code.name.monkey.retromusic.databinding.FragmentWhatsNewBinding
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.drawAboveSystemBars
|
||||
import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
|
||||
import code.name.monkey.retromusic.extensions.surfaceColor
|
||||
import code.name.monkey.retromusic.extensions.openUrl
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil.lastVersion
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import java.io.BufferedReader
|
||||
import java.io.InputStreamReader
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.util.*
|
||||
|
||||
class WhatsNewActivity : AbsThemeActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
val binding = ActivityWhatsNewBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
setTaskDescriptionColorAuto()
|
||||
binding.toolbar.setNavigationOnClickListener { onBackPressed() }
|
||||
ToolbarContentTintHelper.colorBackButton(binding.toolbar)
|
||||
class WhatsNewFragment : BottomSheetDialogFragment() {
|
||||
private var _binding: FragmentWhatsNewBinding? = null
|
||||
val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View {
|
||||
_binding = FragmentWhatsNewBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
try {
|
||||
val buf = StringBuilder()
|
||||
val json = assets.open("retro-changelog.html")
|
||||
BufferedReader(InputStreamReader(json, StandardCharsets.UTF_8)).use { br ->
|
||||
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) {
|
||||
buf.append(str)
|
||||
|
@ -44,31 +50,29 @@ class WhatsNewActivity : AbsThemeActivity() {
|
|||
}
|
||||
|
||||
// Inject color values for WebView body background and links
|
||||
val isDark = isWindowBackgroundDark(this)
|
||||
val accentColor = accentColor(this)
|
||||
val backgroundColor = colorToCSS(
|
||||
surfaceColor(Color.parseColor(if (isDark) "#424242" else "#ffffff"))
|
||||
)
|
||||
val isDark = isWindowBackgroundDark(requireContext())
|
||||
val accentColor = accentColor()
|
||||
binding.webView.setBackgroundColor(0)
|
||||
val contentColor = colorToCSS(Color.parseColor(if (isDark) "#ffffff" else "#000000"))
|
||||
val textColor = colorToCSS(Color.parseColor(if (isDark) "#60FFFFFF" else "#80000000"))
|
||||
val accentColorString = colorToCSS(accentColor(this))
|
||||
val accentColorString = colorToCSS(accentColor())
|
||||
val cardBackgroundColor =
|
||||
colorToCSS(Color.parseColor(if (isDark) "#353535" else "#ffffff"))
|
||||
val accentTextColor = colorToCSS(
|
||||
getPrimaryTextColor(
|
||||
this, isColorLight(accentColor)
|
||||
requireContext(), isColorLight(accentColor)
|
||||
)
|
||||
)
|
||||
val changeLog = buf.toString()
|
||||
.replace(
|
||||
"{style-placeholder}",
|
||||
"body { background-color: $backgroundColor; color: $contentColor; } li {color: $textColor;} h3 {color: $accentColorString;} .tag {background-color: $accentColorString; color: $accentTextColor; } div{background-color: $cardBackgroundColor;}"
|
||||
"body { color: $contentColor; } li {color: $textColor;} h3 {color: $accentColorString;} .tag {background-color: $accentColorString; color: $accentTextColor; } div{background-color: $cardBackgroundColor;}"
|
||||
)
|
||||
.replace("{link-color}", colorToCSS(accentColor(this)))
|
||||
.replace("{link-color}", colorToCSS(accentColor()))
|
||||
.replace(
|
||||
"{link-color-active}",
|
||||
colorToCSS(
|
||||
lightenColor(accentColor(this))
|
||||
lightenColor(accentColor())
|
||||
)
|
||||
)
|
||||
binding.webView.loadData(changeLog, "text/html", "UTF-8")
|
||||
|
@ -77,12 +81,9 @@ class WhatsNewActivity : AbsThemeActivity() {
|
|||
"<h1>Unable to load</h1><p>" + e.localizedMessage + "</p>", "text/html", "UTF-8"
|
||||
)
|
||||
}
|
||||
setChangelogRead(this)
|
||||
setChangelogRead(requireContext())
|
||||
binding.tgFab.setOnClickListener {
|
||||
RetroUtil.openUrl(
|
||||
this,
|
||||
Constants.TELEGRAM_CHANGE_LOG
|
||||
)
|
||||
openUrl(Constants.TELEGRAM_CHANGE_LOG)
|
||||
}
|
||||
binding.tgFab.accentColor()
|
||||
binding.tgFab.shrink()
|
||||
|
@ -94,10 +95,16 @@ class WhatsNewActivity : AbsThemeActivity() {
|
|||
binding.tgFab.extend()
|
||||
}
|
||||
}
|
||||
binding.webView.drawAboveSystemBars()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
const val TAG = "WhatsNewFragment"
|
||||
private fun colorToCSS(color: Int): String {
|
||||
return String.format(
|
||||
Locale.getDefault(),
|
||||
|
@ -112,11 +119,20 @@ class WhatsNewActivity : AbsThemeActivity() {
|
|||
private fun setChangelogRead(context: Context) {
|
||||
try {
|
||||
val pInfo = context.packageManager.getPackageInfo(context.packageName, 0)
|
||||
val currentVersion = pInfo.versionCode
|
||||
val currentVersion = PackageInfoCompat.getLongVersionCode(pInfo)
|
||||
lastVersion = currentVersion
|
||||
} catch (e: PackageManager.NameNotFoundException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
fun showChangeLog(activity: FragmentActivity) {
|
||||
val pInfo = activity.packageManager.getPackageInfo(activity.packageName, 0)
|
||||
val currentVersion = PackageInfoCompat.getLongVersionCode(pInfo)
|
||||
if (currentVersion > lastVersion && !BuildConfig.DEBUG) {
|
||||
val changelogBottomSheet = WhatsNewFragment()
|
||||
changelogBottomSheet.show(activity.supportFragmentManager, TAG)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,9 +29,9 @@ import android.view.inputmethod.InputMethodManager
|
|||
import android.widget.EditText
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
|
||||
abstract class AbsBaseActivity : AbsThemeActivity() {
|
||||
|
@ -90,19 +90,15 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
|
|||
}
|
||||
|
||||
protected open fun requestPermissions() {
|
||||
if (VersionUtils.hasMarshmallow()) {
|
||||
requestPermissions(permissions, PERMISSION_REQUEST)
|
||||
}
|
||||
ActivityCompat.requestPermissions(this, permissions, PERMISSION_REQUEST)
|
||||
}
|
||||
|
||||
protected fun hasPermissions(): Boolean {
|
||||
if (VersionUtils.hasMarshmallow()) {
|
||||
for (permission in permissions) {
|
||||
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (ActivityCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -126,14 +122,15 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
|
|||
Snackbar.LENGTH_INDEFINITE
|
||||
)
|
||||
.setAction(R.string.action_grant) { requestPermissions() }
|
||||
.setActionTextColor(ThemeStore.accentColor(this)).show()
|
||||
.setActionTextColor(accentColor()).show()
|
||||
} else {
|
||||
// User has deny permission and checked never show permission dialog so you can redirect to Application settings page
|
||||
Snackbar.make(
|
||||
snackBarContainer,
|
||||
permissionDeniedMessage!!,
|
||||
Snackbar.LENGTH_INDEFINITE
|
||||
).setAction(R.string.action_settings) {
|
||||
)
|
||||
.setAction(R.string.action_settings) {
|
||||
val intent = Intent()
|
||||
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
|
||||
val uri = Uri.fromParts(
|
||||
|
@ -143,7 +140,7 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
|
|||
)
|
||||
intent.data = uri
|
||||
startActivity(intent)
|
||||
}.setActionTextColor(ThemeStore.accentColor(this)).show()
|
||||
}.setActionTextColor(accentColor()).show()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -156,6 +153,7 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
|
|||
companion object {
|
||||
const val PERMISSION_REQUEST = 100
|
||||
}
|
||||
|
||||
// this lets keyboard close when clicked in backgroud
|
||||
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
|
||||
if (event.action == MotionEvent.ACTION_DOWN) {
|
||||
|
@ -165,7 +163,10 @@ abstract class AbsBaseActivity : AbsThemeActivity() {
|
|||
v.getGlobalVisibleRect(outRect)
|
||||
if (!outRect.contains(event.rawX.toInt(), event.rawY.toInt())) {
|
||||
v.clearFocus()
|
||||
getSystemService<InputMethodManager>()?.hideSoftInputFromWindow(v.windowToken, 0)
|
||||
getSystemService<InputMethodManager>()?.hideSoftInputFromWindow(
|
||||
v.windowToken,
|
||||
0
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package code.name.monkey.retromusic.activities.base
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.ViewStub
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.cast.CastHelper
|
||||
import code.name.monkey.retromusic.cast.RetroSessionManager
|
||||
import code.name.monkey.retromusic.cast.RetroSessionManagerListener
|
||||
import code.name.monkey.retromusic.cast.RetroWebServer
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import com.google.android.gms.cast.framework.CastContext
|
||||
|
@ -12,36 +10,40 @@ import com.google.android.gms.cast.framework.CastSession
|
|||
import com.google.android.gms.cast.framework.SessionManager
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
import com.google.android.gms.common.GoogleApiAvailability
|
||||
import org.koin.android.ext.android.inject
|
||||
|
||||
|
||||
abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
|
||||
|
||||
private var mCastSession: CastSession? = null
|
||||
private lateinit var sessionManager: SessionManager
|
||||
private var webServer: RetroWebServer? = null
|
||||
private val webServer: RetroWebServer by inject()
|
||||
|
||||
private var playServicesAvailable: Boolean = false
|
||||
|
||||
private val sessionManagerListener by lazy {
|
||||
object : RetroSessionManager {
|
||||
object : RetroSessionManagerListener {
|
||||
override fun onSessionStarting(castSession: CastSession) {
|
||||
invalidateOptionsMenu()
|
||||
webServer = RetroWebServer.getInstance(this@AbsCastActivity)
|
||||
webServer?.start()
|
||||
webServer.start()
|
||||
}
|
||||
|
||||
override fun onSessionStarted(castSession: CastSession, p1: String) {
|
||||
invalidateOptionsMenu()
|
||||
mCastSession = castSession
|
||||
loadCastQueue(MusicPlayerRemote.position)
|
||||
inflateCastController()
|
||||
loadCastQueue()
|
||||
MusicPlayerRemote.isCasting = true
|
||||
setAllowDragging(false)
|
||||
collapsePanel()
|
||||
}
|
||||
|
||||
override fun onSessionEnding(p0: CastSession) {
|
||||
invalidateOptionsMenu()
|
||||
webServer?.stop()
|
||||
override fun onSessionEnding(castSession: CastSession) {
|
||||
MusicPlayerRemote.isCasting = false
|
||||
castSession.remoteMediaClient?.let {
|
||||
val position = it.mediaQueue.indexOfItemWithId(it.currentItem?.itemId ?: 0)
|
||||
val progress = it.approximateStreamPosition
|
||||
MusicPlayerRemote.position = position
|
||||
MusicPlayerRemote.seekTo(progress.toInt())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSessionEnded(castSession: CastSession, p1: Int) {
|
||||
|
@ -49,15 +51,18 @@ abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
|
|||
if (mCastSession == castSession) {
|
||||
mCastSession = null
|
||||
}
|
||||
MusicPlayerRemote.isCasting = false
|
||||
setAllowDragging(true)
|
||||
webServer.stop()
|
||||
}
|
||||
|
||||
override fun onSessionResumed(castSession: CastSession, p1: Boolean) {
|
||||
invalidateOptionsMenu()
|
||||
mCastSession = castSession
|
||||
loadCastQueue(MusicPlayerRemote.position)
|
||||
inflateCastController()
|
||||
webServer.start()
|
||||
mCastSession?.remoteMediaClient?.let {
|
||||
loadCastQueue(it.mediaQueue.indexOfItemWithId(it.currentItem?.itemId ?: 0), it.approximateStreamPosition)
|
||||
}
|
||||
|
||||
MusicPlayerRemote.isCasting = true
|
||||
setAllowDragging(false)
|
||||
collapsePanel()
|
||||
|
@ -70,6 +75,7 @@ abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
|
|||
}
|
||||
MusicPlayerRemote.isCasting = false
|
||||
setAllowDragging(true)
|
||||
webServer.stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,10 +94,11 @@ abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
|
|||
}
|
||||
|
||||
private fun setupCast() {
|
||||
sessionManager = CastContext.getSharedInstance(applicationContext).sessionManager
|
||||
sessionManager = CastContext.getSharedInstance(this).sessionManager
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (playServicesAvailable) {
|
||||
sessionManager.addSessionManagerListener(
|
||||
sessionManagerListener,
|
||||
|
@ -101,41 +108,39 @@ abstract class AbsCastActivity : AbsSlidingMusicPanelActivity() {
|
|||
mCastSession = sessionManager.currentCastSession
|
||||
}
|
||||
}
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (playServicesAvailable) {
|
||||
sessionManager.removeSessionManagerListener(
|
||||
sessionManagerListener,
|
||||
CastSession::class.java
|
||||
)
|
||||
mCastSession = null
|
||||
}
|
||||
|
||||
private fun songChanged(position: Int) {
|
||||
loadCastQueue(position)
|
||||
}
|
||||
|
||||
fun loadCastQueue(position: Int) {
|
||||
if (!MusicPlayerRemote.playingQueue.isNullOrEmpty()) {
|
||||
fun loadCastQueue(
|
||||
position: Int = MusicPlayerRemote.position,
|
||||
progress: Long = MusicPlayerRemote.songProgressMillis.toLong(),
|
||||
) {
|
||||
mCastSession?.let {
|
||||
if (!MusicPlayerRemote.playingQueue.isNullOrEmpty()) {
|
||||
CastHelper.castQueue(
|
||||
it,
|
||||
MusicPlayerRemote.playingQueue,
|
||||
position,
|
||||
MusicPlayerRemote.songProgressMillis.toLong()
|
||||
progress
|
||||
)
|
||||
}
|
||||
} else {
|
||||
mCastSession?.let { CastHelper.castSong(it, MusicPlayerRemote.currentSong) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPlayingMetaChanged() {
|
||||
super.onPlayingMetaChanged()
|
||||
override fun onQueueChanged() {
|
||||
super.onQueueChanged()
|
||||
if (playServicesAvailable) {
|
||||
songChanged(MusicPlayerRemote.position)
|
||||
loadCastQueue()
|
||||
}
|
||||
}
|
||||
|
||||
fun inflateCastController() {
|
||||
findViewById<ViewStub>(R.id.cast_stub)?.inflate()
|
||||
}
|
||||
}
|
|
@ -30,7 +30,6 @@ import androidx.fragment.app.Fragment
|
|||
import androidx.fragment.app.commit
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.RetroBottomSheetBehavior
|
||||
import code.name.monkey.retromusic.databinding.SlidingMusicPanelLayoutBinding
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
|
@ -60,6 +59,7 @@ import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
|||
import code.name.monkey.retromusic.model.CategoryInfo
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.ViewUtil
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior.*
|
||||
import org.koin.androidx.viewmodel.ext.android.viewModel
|
||||
|
||||
|
@ -72,7 +72,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
var fromNotification = false
|
||||
private var windowInsets: WindowInsetsCompat? = null
|
||||
protected val libraryViewModel by viewModel<LibraryViewModel>()
|
||||
private lateinit var bottomSheetBehavior: RetroBottomSheetBehavior<FrameLayout>
|
||||
private lateinit var bottomSheetBehavior: BottomSheetBehavior<FrameLayout>
|
||||
private var playerFragment: AbsPlayerFragment? = null
|
||||
private var miniPlayerFragment: MiniPlayerFragment? = null
|
||||
private var nowPlayingScreen: NowPlayingScreen? = null
|
||||
|
@ -122,6 +122,9 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
fromNotification = false
|
||||
}
|
||||
}
|
||||
STATE_HIDDEN -> {
|
||||
MusicPlayerRemote.clearQueue()
|
||||
}
|
||||
else -> {
|
||||
println("Do a flip")
|
||||
}
|
||||
|
@ -154,9 +157,9 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
}
|
||||
|
||||
private fun setupBottomSheet() {
|
||||
bottomSheetBehavior = from(binding.slidingPanel) as RetroBottomSheetBehavior
|
||||
bottomSheetBehavior = from(binding.slidingPanel)
|
||||
bottomSheetBehavior.addBottomSheetCallback(bottomSheetCallbackList)
|
||||
bottomSheetBehavior.isHideable = false
|
||||
bottomSheetBehavior.isHideable = true
|
||||
setMiniPlayerAlphaProgress(0F)
|
||||
}
|
||||
|
||||
|
@ -294,7 +297,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
navigationBarColor = surfaceColor()
|
||||
setTaskDescColor(paletteColor)
|
||||
val isColorLight = paletteColor.isColorLight
|
||||
if (PreferenceUtil.isAdaptiveColor && (nowPlayingScreen == Normal || nowPlayingScreen == Flat)) {
|
||||
if (PreferenceUtil.isAdaptiveColor && (nowPlayingScreen == Normal || nowPlayingScreen == Flat || nowPlayingScreen == Material)) {
|
||||
setLightNavigationBar(true)
|
||||
setLightStatusBar(isColorLight)
|
||||
} else if (nowPlayingScreen == Card || nowPlayingScreen == Blur || nowPlayingScreen == BlurCard) {
|
||||
|
@ -363,18 +366,15 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
)
|
||||
return
|
||||
}
|
||||
val translationY =
|
||||
if (visible) 0F else dip(R.dimen.bottom_nav_height).toFloat() + windowInsets.safeGetBottomInsets()
|
||||
val mAnimate = animate && bottomSheetBehavior.state == STATE_COLLAPSED
|
||||
if (mAnimate) {
|
||||
binding.bottomNavigationView.translateYAnimate(translationY).doOnEnd {
|
||||
if (visible && bottomSheetBehavior.state != STATE_EXPANDED) {
|
||||
if (visible) {
|
||||
binding.bottomNavigationView.bringToFront()
|
||||
}
|
||||
binding.bottomNavigationView.show()
|
||||
} else {
|
||||
binding.bottomNavigationView.hide()
|
||||
}
|
||||
} else {
|
||||
binding.bottomNavigationView.translationY =
|
||||
translationY
|
||||
binding.bottomNavigationView.isVisible = false
|
||||
if (visible && bottomSheetBehavior.state != STATE_EXPANDED) {
|
||||
binding.bottomNavigationView.bringToFront()
|
||||
|
@ -399,7 +399,10 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
if (hide) {
|
||||
bottomSheetBehavior.peekHeight = -windowInsets.safeGetBottomInsets()
|
||||
bottomSheetBehavior.state = STATE_COLLAPSED
|
||||
libraryViewModel.setFabMargin(if (isBottomNavVisible) dip(R.dimen.bottom_nav_height) else 0)
|
||||
libraryViewModel.setFabMargin(
|
||||
this,
|
||||
if (isBottomNavVisible) dip(R.dimen.bottom_nav_height) else 0
|
||||
)
|
||||
} else {
|
||||
if (MusicPlayerRemote.playingQueue.isNotEmpty()) {
|
||||
binding.slidingPanel.elevation = 0F
|
||||
|
@ -411,7 +414,7 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
} else {
|
||||
bottomSheetBehavior.peekHeight = heightOfBarWithTabs
|
||||
}
|
||||
libraryViewModel.setFabMargin(dip(R.dimen.mini_player_height_expanded))
|
||||
libraryViewModel.setFabMargin(this, dip(R.dimen.mini_player_height_expanded))
|
||||
} else {
|
||||
println("Details")
|
||||
if (animate) {
|
||||
|
@ -422,14 +425,14 @@ abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
|
|||
bottomSheetBehavior.peekHeight = heightOfBar
|
||||
binding.slidingPanel.bringToFront()
|
||||
}
|
||||
libraryViewModel.setFabMargin(dip(R.dimen.mini_player_height))
|
||||
libraryViewModel.setFabMargin(this, dip(R.dimen.mini_player_height))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setAllowDragging(allowDragging: Boolean) {
|
||||
bottomSheetBehavior.setAllowDragging(allowDragging)
|
||||
bottomSheetBehavior.isDraggable = allowDragging
|
||||
hideBottomSheet(false)
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import android.content.Context
|
|||
import android.content.res.Resources
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
import androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode
|
||||
|
@ -28,12 +29,13 @@ import code.name.monkey.retromusic.LanguageContextWrapper
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.theme.ThemeManager
|
||||
import code.name.monkey.retromusic.util.theme.getNightMode
|
||||
import code.name.monkey.retromusic.util.theme.getThemeResValue
|
||||
import java.util.*
|
||||
|
||||
abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
|
||||
|
||||
private val handler = Handler()
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
updateTheme()
|
||||
|
@ -50,9 +52,9 @@ abstract class AbsThemeActivity : ATHToolbarActivity(), Runnable {
|
|||
}
|
||||
|
||||
private fun updateTheme() {
|
||||
setTheme(ThemeManager.getThemeResValue())
|
||||
setTheme(getThemeResValue())
|
||||
if (PreferenceUtil.materialYou) {
|
||||
setDefaultNightMode(ThemeManager.getNightMode())
|
||||
setDefaultNightMode(getNightMode())
|
||||
}
|
||||
|
||||
if (PreferenceUtil.isCustomFont) {
|
||||
|
|
|
@ -20,13 +20,11 @@ import android.content.Intent
|
|||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.StringDef
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.net.toUri
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.util.MaterialUtil
|
||||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
|
@ -38,7 +36,9 @@ import code.name.monkey.retromusic.activities.bugreport.model.github.ExtraInfo
|
|||
import code.name.monkey.retromusic.activities.bugreport.model.github.GithubLogin
|
||||
import code.name.monkey.retromusic.activities.bugreport.model.github.GithubTarget
|
||||
import code.name.monkey.retromusic.databinding.ActivityBugReportBinding
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
|
||||
import code.name.monkey.retromusic.extensions.showToast
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
|
@ -87,7 +87,7 @@ open class BugReportActivity : AbsThemeActivity() {
|
|||
}
|
||||
|
||||
private fun initViews() {
|
||||
val accentColor = ThemeStore.accentColor(this)
|
||||
val accentColor = accentColor()
|
||||
setSupportActionBar(binding.toolbar)
|
||||
ToolbarContentTintHelper.colorBackButton(binding.toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
|
@ -163,11 +163,7 @@ open class BugReportActivity : AbsThemeActivity() {
|
|||
val clipboard = getSystemService<ClipboardManager>()
|
||||
val clip = ClipData.newPlainText(getString(R.string.device_info), deviceInfo?.toMarkdown())
|
||||
clipboard?.setPrimaryClip(clip)
|
||||
Toast.makeText(
|
||||
this@BugReportActivity,
|
||||
R.string.copied_device_info_to_clipboard,
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
showToast(R.string.copied_device_info_to_clipboard)
|
||||
}
|
||||
|
||||
private fun validateInput(): Boolean {
|
||||
|
@ -314,6 +310,7 @@ open class BugReportActivity : AbsThemeActivity() {
|
|||
|
||||
private const val STATUS_BAD_CREDENTIALS = 401
|
||||
private const val STATUS_ISSUES_NOT_ENABLED = 410
|
||||
private const val ISSUE_TRACKER_LINK = "https://github.com/RetroMusicPlayer/RetroMusicPlayer"
|
||||
private const val ISSUE_TRACKER_LINK =
|
||||
"https://github.com/RetroMusicPlayer/RetroMusicPlayer"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Context
|
|||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import androidx.annotation.IntRange
|
||||
import androidx.core.content.pm.PackageInfoCompat
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil.isAdaptiveColor
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil.languageCode
|
||||
|
@ -35,7 +36,7 @@ class DeviceInfo(context: Context) {
|
|||
|
||||
@IntRange(from = 0)
|
||||
private val sdkVersion = Build.VERSION.SDK_INT
|
||||
private var versionCode = 0
|
||||
private var versionCode = 0L
|
||||
private var versionName: String? = null
|
||||
private val selectedLang: String
|
||||
fun toMarkdown(): String {
|
||||
|
@ -96,7 +97,7 @@ class DeviceInfo(context: Context) {
|
|||
null
|
||||
}
|
||||
if (packageInfo != null) {
|
||||
versionCode = packageInfo.versionCode
|
||||
versionCode = PackageInfoCompat.getLongVersionCode(packageInfo)
|
||||
versionName = packageInfo.versionName
|
||||
} else {
|
||||
versionCode = -1
|
||||
|
|
|
@ -41,11 +41,12 @@ import code.name.monkey.retromusic.R.drawable
|
|||
import code.name.monkey.retromusic.activities.base.AbsBaseActivity
|
||||
import code.name.monkey.retromusic.activities.saf.SAFGuideActivity
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.colorButtons
|
||||
import code.name.monkey.retromusic.extensions.hideSoftKeyboard
|
||||
import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
|
||||
import code.name.monkey.retromusic.model.ArtworkInfo
|
||||
import code.name.monkey.retromusic.model.AudioTagInfo
|
||||
import code.name.monkey.retromusic.repository.Repository
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import code.name.monkey.retromusic.util.SAFUtil
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
@ -92,7 +93,9 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
|||
2 -> deleteImage()
|
||||
}
|
||||
}
|
||||
.setNegativeButton(R.string.action_cancel, null)
|
||||
.show()
|
||||
.colorButtons()
|
||||
|
||||
internal val albumArtist: String?
|
||||
get() {
|
||||
|
@ -346,7 +349,7 @@ abstract class AbsTagEditorActivity<VB : ViewBinding> : AbsBaseActivity() {
|
|||
fieldKeyValueMap: Map<FieldKey, String>,
|
||||
artworkInfo: ArtworkInfo?
|
||||
) {
|
||||
RetroUtil.hideSoftKeyboard(this)
|
||||
hideSoftKeyboard()
|
||||
|
||||
hideFab()
|
||||
println(fieldKeyValueMap)
|
||||
|
|
|
@ -30,10 +30,7 @@ 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.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.*
|
||||
import code.name.monkey.retromusic.glide.GlideApp
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
||||
import code.name.monkey.retromusic.model.ArtworkInfo
|
||||
|
@ -117,11 +114,7 @@ class AlbumTagEditorActivity : AbsTagEditorActivity<ActivityAlbumTagEditorBindin
|
|||
}
|
||||
|
||||
private fun toastLoadingFailed() {
|
||||
Toast.makeText(
|
||||
this@AlbumTagEditorActivity,
|
||||
R.string.could_not_download_album_cover,
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
showToast(R.string.could_not_download_album_cover)
|
||||
}
|
||||
|
||||
override fun searchImageOnWeb() {
|
||||
|
@ -161,8 +154,7 @@ class AlbumTagEditorActivity : AbsTagEditorActivity<ActivityAlbumTagEditorBindin
|
|||
|
||||
override fun onLoadFailed(errorDrawable: Drawable?) {
|
||||
super.onLoadFailed(errorDrawable)
|
||||
Toast.makeText(this@AlbumTagEditorActivity, "Load Failed", Toast.LENGTH_LONG)
|
||||
.show()
|
||||
showToast("Load Failed", Toast.LENGTH_LONG)
|
||||
}
|
||||
|
||||
override fun setResource(resource: BitmapPaletteWrapper?) {}
|
||||
|
|
|
@ -30,10 +30,7 @@ import androidx.core.widget.doAfterTextChanged
|
|||
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.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.*
|
||||
import code.name.monkey.retromusic.glide.GlideApp
|
||||
import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
|
||||
import code.name.monkey.retromusic.model.ArtworkInfo
|
||||
|
@ -196,8 +193,7 @@ class SongTagEditorActivity : AbsTagEditorActivity<ActivitySongTagEditorBinding>
|
|||
|
||||
override fun onLoadFailed(errorDrawable: Drawable?) {
|
||||
super.onLoadFailed(errorDrawable)
|
||||
Toast.makeText(this@SongTagEditorActivity, "Load Failed", Toast.LENGTH_LONG)
|
||||
.show()
|
||||
showToast("Load Failed", Toast.LENGTH_LONG)
|
||||
}
|
||||
|
||||
override fun setResource(resource: BitmapPaletteWrapper?) {}
|
||||
|
|
|
@ -6,8 +6,8 @@ import android.graphics.Bitmap
|
|||
import android.media.MediaScannerConnection
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import code.name.monkey.retromusic.extensions.showToast
|
||||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener
|
||||
import code.name.monkey.retromusic.model.AudioTagInfo
|
||||
import code.name.monkey.retromusic.util.MusicUtil.createAlbumArtFile
|
||||
|
@ -24,7 +24,6 @@ import org.jaudiotagger.tag.TagException
|
|||
import org.jaudiotagger.tag.images.AndroidArtwork
|
||||
import org.jaudiotagger.tag.images.Artwork
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.io.IOException
|
||||
|
||||
class TagWriter {
|
||||
|
@ -34,7 +33,7 @@ class TagWriter {
|
|||
suspend fun scan(context: Context, toBeScanned: List<String?>?) {
|
||||
if (toBeScanned == null || toBeScanned.isEmpty()) {
|
||||
Log.i("scan", "scan: Empty")
|
||||
Toast.makeText(context, "Scan file from folder", Toast.LENGTH_SHORT).show()
|
||||
context.showToast( "Scan file from folder")
|
||||
return
|
||||
}
|
||||
MediaScannerConnection.scanFile(
|
||||
|
@ -60,7 +59,7 @@ class TagWriter {
|
|||
info.artworkInfo.artwork.compress(
|
||||
Bitmap.CompressFormat.JPEG,
|
||||
100,
|
||||
FileOutputStream(albumArtFile)
|
||||
albumArtFile.outputStream()
|
||||
)
|
||||
artwork = AndroidArtwork.createArtworkFromFile(albumArtFile)
|
||||
} catch (e: IOException) {
|
||||
|
@ -133,7 +132,7 @@ class TagWriter {
|
|||
info.artworkInfo.artwork.compress(
|
||||
Bitmap.CompressFormat.JPEG,
|
||||
100,
|
||||
FileOutputStream(albumArtFile)
|
||||
albumArtFile.outputStream()
|
||||
)
|
||||
artwork = AndroidArtwork.createArtworkFromFile(albumArtFile)
|
||||
} catch (e: IOException) {
|
||||
|
|
|
@ -19,12 +19,12 @@ import android.view.LayoutInflater
|
|||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.PreferenceDialogLibraryCategoriesListitemBinding
|
||||
import code.name.monkey.retromusic.extensions.showToast
|
||||
import code.name.monkey.retromusic.model.CategoryInfo
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.SwipeAndDragHelper
|
||||
|
@ -59,12 +59,7 @@ class CategoryInfoAdapter : RecyclerView.Adapter<CategoryInfoAdapter.ViewHolder>
|
|||
categoryInfo.visible = !categoryInfo.visible
|
||||
holder.binding.checkbox.isChecked = categoryInfo.visible
|
||||
} else {
|
||||
Toast.makeText(
|
||||
holder.itemView.context,
|
||||
R.string.you_have_to_select_at_least_one_category,
|
||||
Toast.LENGTH_SHORT
|
||||
)
|
||||
.show()
|
||||
holder.itemView.context.showToast(R.string.you_have_to_select_at_least_one_category)
|
||||
}
|
||||
}
|
||||
holder.binding.dragView.setOnTouchListener { _: View?, event: MotionEvent ->
|
||||
|
|
|
@ -14,15 +14,14 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.adapter
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.extensions.openUrl
|
||||
import code.name.monkey.retromusic.model.Contributor
|
||||
import code.name.monkey.retromusic.util.RetroUtil.openUrl
|
||||
import code.name.monkey.retromusic.views.RetroShapeableImageView
|
||||
import com.bumptech.glide.Glide
|
||||
|
||||
|
@ -65,7 +64,7 @@ class ContributorAdapter(
|
|||
val contributor = contributors[position]
|
||||
holder.bindData(contributor)
|
||||
holder.itemView.setOnClickListener {
|
||||
openUrl(it?.context as Activity, contributors[position].link)
|
||||
it?.context?.openUrl(contributors[position].link)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,13 +25,13 @@ import code.name.monkey.appthemehelper.util.ATHUtil
|
|||
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.ICabHolder
|
||||
import code.name.monkey.retromusic.interfaces.ICallbacks
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.signature.MediaStoreSignature
|
||||
import me.zhanghai.android.fastscroll.PopupTextProvider
|
||||
|
@ -45,7 +45,7 @@ class SongFileAdapter(
|
|||
private var dataSet: List<File>,
|
||||
private val itemLayoutRes: Int,
|
||||
private val iCallbacks: ICallbacks?,
|
||||
iCabHolder: ICabHolder?
|
||||
iCabHolder: ICabHolder?,
|
||||
) : AbsMultiSelectAdapter<SongFileAdapter.ViewHolder, File>(
|
||||
activity, iCabHolder, R.menu.menu_media_selection
|
||||
), PopupTextProvider {
|
||||
|
@ -110,9 +110,7 @@ class SongFileAdapter(
|
|||
)
|
||||
)
|
||||
} else {
|
||||
val error = RetroUtil.getTintedVectorDrawable(
|
||||
activity, R.drawable.ic_file_music, iconColor
|
||||
)
|
||||
val error = activity.getTintedDrawable(R.drawable.ic_file_music, iconColor)
|
||||
GlideApp.with(activity)
|
||||
.load(AudioFileCover(file.path))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
|
@ -132,8 +130,8 @@ class SongFileAdapter(
|
|||
return dataSet[position]
|
||||
}
|
||||
|
||||
override fun getName(`object`: File): String {
|
||||
return getFileTitle(`object`)
|
||||
override fun getName(model: File): String {
|
||||
return getFileTitle(model)
|
||||
}
|
||||
|
||||
override fun onMultipleItemAction(menuItem: MenuItem, selection: List<File>) {
|
||||
|
|
|
@ -91,9 +91,9 @@ open class AlbumAdapter(
|
|||
// Check if imageContainer exists so we can have a smooth transition without
|
||||
// CardView clipping, if it doesn't exist in current layout set transition name to image instead.
|
||||
if (holder.imageContainer != null) {
|
||||
holder.imageContainer!!.setTransitionName(album.id.toString())
|
||||
holder.imageContainer?.transitionName = album.id.toString()
|
||||
} else {
|
||||
holder.image!!.setTransitionName(album.id.toString())
|
||||
holder.image?.transitionName = album.id.toString()
|
||||
}
|
||||
loadAlbumCover(album, holder)
|
||||
}
|
||||
|
@ -135,8 +135,8 @@ open class AlbumAdapter(
|
|||
return dataSet[position]
|
||||
}
|
||||
|
||||
override fun getName(album: Album): String {
|
||||
return album.title
|
||||
override fun getName(model: Album): String {
|
||||
return model.title
|
||||
}
|
||||
|
||||
override fun onMultipleItemAction(
|
||||
|
|
|
@ -85,7 +85,6 @@ class AlbumCoverPagerAdapter(
|
|||
|
||||
class AlbumCoverFragment : Fragment() {
|
||||
|
||||
private lateinit var albumCover: ImageView
|
||||
private var isColorReady: Boolean = false
|
||||
private lateinit var color: MediaNotificationProcessor
|
||||
private lateinit var song: Song
|
||||
|
@ -106,8 +105,6 @@ class AlbumCoverPagerAdapter(
|
|||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
val view = inflater.inflate(getLayoutWithPlayerTheme(), container, false)
|
||||
view.setTransitionName("lyrics")
|
||||
albumCover = view.findViewById(R.id.player_image)
|
||||
view.setOnClickListener {
|
||||
if (mainActivity.getBottomSheetBehavior().state == STATE_EXPANDED) {
|
||||
showLyricsDialog()
|
||||
|
@ -158,7 +155,7 @@ class AlbumCoverPagerAdapter(
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
loadAlbumCover()
|
||||
loadAlbumCover(albumCover = view.findViewById(R.id.player_image))
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
@ -166,7 +163,7 @@ class AlbumCoverPagerAdapter(
|
|||
colorReceiver = null
|
||||
}
|
||||
|
||||
private fun loadAlbumCover() {
|
||||
private fun loadAlbumCover(albumCover: ImageView) {
|
||||
GlideApp.with(this).asBitmapPalette().songCoverOptions(song)
|
||||
//.checkIgnoreMediaStore()
|
||||
.load(RetroGlideExtension.getSongModel(song))
|
||||
|
|
|
@ -92,9 +92,9 @@ class ArtistAdapter(
|
|||
val transitionName =
|
||||
if (albumArtistsOnly) artist.name else artist.id.toString()
|
||||
if (holder.imageContainer != null) {
|
||||
holder.imageContainer!!.setTransitionName(transitionName)
|
||||
holder.imageContainer?.transitionName = transitionName
|
||||
} else {
|
||||
holder.image!!.setTransitionName(transitionName)
|
||||
holder.image?.transitionName = transitionName
|
||||
}
|
||||
loadArtistImage(artist, holder)
|
||||
}
|
||||
|
@ -132,8 +132,8 @@ class ArtistAdapter(
|
|||
return dataSet[position]
|
||||
}
|
||||
|
||||
override fun getName(artist: Artist): String {
|
||||
return artist.name
|
||||
override fun getName(model: Artist): String {
|
||||
return model.name
|
||||
}
|
||||
|
||||
override fun onMultipleItemAction(
|
||||
|
|
|
@ -64,9 +64,8 @@ abstract class AbsMultiSelectAdapter<V : RecyclerView.ViewHolder?, I>(
|
|||
}
|
||||
|
||||
protected abstract fun getIdentifier(position: Int): I?
|
||||
protected open fun getName(i: I): String? {
|
||||
return i.toString()
|
||||
}
|
||||
|
||||
protected abstract fun getName(model: I): String?
|
||||
|
||||
protected fun isChecked(identifier: I): Boolean {
|
||||
return checked.contains(identifier)
|
||||
|
|
|
@ -120,8 +120,8 @@ class PlaylistAdapter(
|
|||
return dataSet[position]
|
||||
}
|
||||
|
||||
override fun getName(playlist: PlaylistWithSongs): String {
|
||||
return playlist.playlistEntity.playlistName
|
||||
override fun getName(model: PlaylistWithSongs): String {
|
||||
return model.playlistEntity.playlistName
|
||||
}
|
||||
|
||||
override fun onMultipleItemAction(menuItem: MenuItem, selection: List<PlaylistWithSongs>) {
|
||||
|
@ -163,7 +163,7 @@ class PlaylistAdapter(
|
|||
if (isInQuickSelectMode) {
|
||||
toggleChecked(layoutPosition)
|
||||
} else {
|
||||
itemView.setTransitionName("playlist")
|
||||
itemView.transitionName = "playlist"
|
||||
listener.onPlaylistClick(dataSet[layoutPosition], itemView)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ class ShuffleButtonSongAdapter(
|
|||
}
|
||||
} else {
|
||||
super.onBindViewHolder(holder, position - 1)
|
||||
val landscape = RetroUtil.isLandscape()
|
||||
val landscape = RetroUtil.isLandscape
|
||||
if ((PreferenceUtil.songGridSize > 2 && !landscape) || (PreferenceUtil.songGridSizeLand > 5 && landscape)) {
|
||||
holder.menu?.isVisible = false
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ open class SongAdapter(
|
|||
holder.text?.text = getSongText(song)
|
||||
holder.text2?.text = getSongText(song)
|
||||
loadAlbumCover(song, holder)
|
||||
val landscape = RetroUtil.isLandscape()
|
||||
val landscape = RetroUtil.isLandscape
|
||||
if ((PreferenceUtil.songGridSize > 2 && !landscape) || (PreferenceUtil.songGridSizeLand > 5 && landscape)) {
|
||||
holder.menu?.isVisible = false
|
||||
}
|
||||
|
@ -149,8 +149,8 @@ open class SongAdapter(
|
|||
return dataSet[position]
|
||||
}
|
||||
|
||||
override fun getName(song: Song): String {
|
||||
return song.title
|
||||
override fun getName(model: Song): String {
|
||||
return model.title
|
||||
}
|
||||
|
||||
override fun onMultipleItemAction(menuItem: MenuItem, selection: List<Song>) {
|
||||
|
|
|
@ -15,19 +15,16 @@
|
|||
package code.name.monkey.retromusic.appshortcuts
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.Icon
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.os.Build
|
||||
import android.util.TypedValue
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.graphics.applyCanvas
|
||||
import androidx.core.graphics.createBitmap
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.extensions.getTintedDrawable
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N_MR1)
|
||||
object AppShortcutIconGenerator {
|
||||
|
@ -64,25 +61,17 @@ object AppShortcutIconGenerator {
|
|||
context: Context,
|
||||
iconId: Int,
|
||||
foregroundColor: Int,
|
||||
backgroundColor: Int
|
||||
backgroundColor: Int,
|
||||
): Icon {
|
||||
// Get and tint foreground and background drawables
|
||||
val vectorDrawable = RetroUtil.getTintedVectorDrawable(context, iconId, foregroundColor)
|
||||
val backgroundDrawable = RetroUtil.getTintedVectorDrawable(
|
||||
context, R.drawable.ic_app_shortcut_background, backgroundColor
|
||||
)
|
||||
val vectorDrawable = context.getTintedDrawable(iconId, foregroundColor)
|
||||
val backgroundDrawable =
|
||||
context.getTintedDrawable(R.drawable.ic_app_shortcut_background, backgroundColor)
|
||||
|
||||
// Squash the two drawables together
|
||||
val layerDrawable = LayerDrawable(arrayOf(backgroundDrawable, vectorDrawable))
|
||||
|
||||
// Return as an Icon
|
||||
return Icon.createWithBitmap(drawableToBitmap(layerDrawable))
|
||||
}
|
||||
|
||||
private fun drawableToBitmap(drawable: Drawable): Bitmap {
|
||||
return createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight).applyCanvas {
|
||||
drawable.setBounds(0, 0, width, height)
|
||||
drawable.draw(this)
|
||||
}
|
||||
return Icon.createWithBitmap(layerDrawable.toBitmap())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,11 +22,13 @@ import android.graphics.Bitmap
|
|||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
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.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
|
||||
|
@ -36,7 +38,7 @@ import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_TOGGLE_
|
|||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.target.SimpleTarget
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
|
||||
|
@ -58,31 +60,24 @@ class AppWidgetBig : BaseAppWidget() {
|
|||
)
|
||||
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
R.id.button_next, context.getTintedDrawable(
|
||||
R.drawable.ic_skip_next,
|
||||
MaterialValueHelper.getPrimaryTextColor(context, false)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
R.id.button_prev,
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_skip_previous,
|
||||
MaterialValueHelper.getPrimaryTextColor(context, false)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
R.id.button_toggle_play_pause,
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_play_arrow_white_32dp,
|
||||
MaterialValueHelper.getPrimaryTextColor(context, false)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
linkButtons(context, appWidgetView)
|
||||
|
@ -123,33 +118,27 @@ class AppWidgetBig : BaseAppWidget() {
|
|||
val playPauseRes =
|
||||
if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow_white_32dp
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_toggle_play_pause,
|
||||
service.getTintedDrawable(
|
||||
playPauseRes,
|
||||
primaryColor
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
// Set prev/next button drawables
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_next,
|
||||
service.getTintedDrawable(
|
||||
R.drawable.ic_skip_next,
|
||||
primaryColor
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_prev,
|
||||
service.getTintedDrawable(
|
||||
R.drawable.ic_skip_previous,
|
||||
primaryColor
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
// Link actions buttons to intents
|
||||
|
@ -167,10 +156,10 @@ class AppWidgetBig : BaseAppWidget() {
|
|||
.asBitmap()
|
||||
//.checkIgnoreMediaStore()
|
||||
.load(RetroGlideExtension.getSongModel(song))
|
||||
.into(object : SimpleTarget<Bitmap>(widgetImageSize, widgetImageSize) {
|
||||
.into(object : CustomTarget<Bitmap>(widgetImageSize, widgetImageSize) {
|
||||
override fun onResourceReady(
|
||||
resource: Bitmap,
|
||||
transition: Transition<in Bitmap>?
|
||||
transition: Transition<in Bitmap>?,
|
||||
) {
|
||||
update(resource)
|
||||
}
|
||||
|
@ -180,6 +169,8 @@ class AppWidgetBig : BaseAppWidget() {
|
|||
update(null)
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {}
|
||||
|
||||
private fun update(bitmap: Bitmap?) {
|
||||
if (bitmap == null) {
|
||||
appWidgetView.setImageViewResource(
|
||||
|
|
|
@ -22,11 +22,13 @@ import android.graphics.Bitmap
|
|||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
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.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.palette.BitmapPaletteWrapper
|
||||
|
@ -34,11 +36,9 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
|
||||
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.ImageUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.target.SimpleTarget
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
|
||||
|
@ -56,31 +56,25 @@ class AppWidgetCard : BaseAppWidget() {
|
|||
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
|
||||
val secondaryColor = MaterialValueHelper.getSecondaryTextColor(context, true)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
R.id.button_next,
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_skip_next,
|
||||
secondaryColor
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
R.id.button_prev,
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_skip_previous,
|
||||
secondaryColor
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
R.id.button_toggle_play_pause,
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_play_arrow_white_32dp,
|
||||
secondaryColor
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
linkButtons(context, appWidgetView)
|
||||
|
@ -109,33 +103,27 @@ class AppWidgetCard : BaseAppWidget() {
|
|||
val playPauseRes =
|
||||
if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow_white_32dp
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_toggle_play_pause,
|
||||
service.getTintedDrawable(
|
||||
playPauseRes,
|
||||
MaterialValueHelper.getSecondaryTextColor(service, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
// Set prev/next button drawables
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_next,
|
||||
service.getTintedDrawable(
|
||||
R.drawable.ic_skip_next,
|
||||
MaterialValueHelper.getSecondaryTextColor(service, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_prev,
|
||||
service.getTintedDrawable(
|
||||
R.drawable.ic_skip_previous,
|
||||
MaterialValueHelper.getSecondaryTextColor(service, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
// Link actions buttons to intents
|
||||
|
@ -158,10 +146,10 @@ class AppWidgetCard : BaseAppWidget() {
|
|||
target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
|
||||
.load(RetroGlideExtension.getSongModel(song))
|
||||
.centerCrop()
|
||||
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
|
||||
.into(object : CustomTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
|
||||
override fun onResourceReady(
|
||||
resource: BitmapPaletteWrapper,
|
||||
transition: Transition<in BitmapPaletteWrapper>?
|
||||
transition: Transition<in BitmapPaletteWrapper>?,
|
||||
) {
|
||||
val palette = resource.palette
|
||||
update(
|
||||
|
@ -180,33 +168,26 @@ class AppWidgetCard : BaseAppWidget() {
|
|||
update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {}
|
||||
|
||||
private fun update(bitmap: Bitmap?, color: Int) {
|
||||
// Set correct drawable for pause state
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service, playPauseRes, color
|
||||
)
|
||||
)
|
||||
R.id.button_toggle_play_pause,
|
||||
service.getTintedDrawable(playPauseRes, color).toBitmap()
|
||||
)
|
||||
|
||||
// Set prev/next button drawables
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service, R.drawable.ic_skip_next, color
|
||||
)
|
||||
)
|
||||
R.id.button_next,
|
||||
service.getTintedDrawable(R.drawable.ic_skip_next, color).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service, R.drawable.ic_skip_previous, color
|
||||
)
|
||||
)
|
||||
R.id.button_prev,
|
||||
service.getTintedDrawable(R.drawable.ic_skip_previous, color).toBitmap()
|
||||
)
|
||||
|
||||
val image = getAlbumArtDrawable(service.resources, bitmap)
|
||||
val image = getAlbumArtDrawable(service, bitmap)
|
||||
val roundedBitmap = createRoundedBitmap(
|
||||
image, imageSize, imageSize, cardRadius, 0F, cardRadius, 0F
|
||||
)
|
||||
|
|
|
@ -21,25 +21,25 @@ import android.content.Intent
|
|||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
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.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.palette.BitmapPaletteWrapper
|
||||
import code.name.monkey.retromusic.service.MusicService
|
||||
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.ImageUtil
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.bumptech.glide.request.target.SimpleTarget
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -58,13 +58,11 @@ class AppWidgetCircle : BaseAppWidget() {
|
|||
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
|
||||
val secondaryColor = MaterialValueHelper.getSecondaryTextColor(context, true)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
R.id.button_toggle_play_pause,
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_play_arrow,
|
||||
secondaryColor
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
linkButtons(context, appWidgetView)
|
||||
|
@ -84,13 +82,11 @@ class AppWidgetCircle : BaseAppWidget() {
|
|||
val playPauseRes =
|
||||
if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_toggle_play_pause,
|
||||
service.getTintedDrawable(
|
||||
playPauseRes,
|
||||
MaterialValueHelper.getSecondaryTextColor(service, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
val isFavorite = runBlocking(Dispatchers.IO) {
|
||||
return@runBlocking MusicUtil.repository.isSongFavorite(song.id)
|
||||
|
@ -98,13 +94,11 @@ class AppWidgetCircle : BaseAppWidget() {
|
|||
val favoriteRes =
|
||||
if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_favorite, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_toggle_favorite,
|
||||
service.getTintedDrawable(
|
||||
favoriteRes,
|
||||
MaterialValueHelper.getSecondaryTextColor(service, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
// Link actions buttons to intents
|
||||
|
@ -122,13 +116,11 @@ class AppWidgetCircle : BaseAppWidget() {
|
|||
}
|
||||
target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
|
||||
.load(RetroGlideExtension.getSongModel(song))
|
||||
.apply(
|
||||
RequestOptions().transform(RoundedCorners(imageSize / 2))
|
||||
)
|
||||
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
|
||||
.apply(RequestOptions.circleCropTransform())
|
||||
.into(object : CustomTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
|
||||
override fun onResourceReady(
|
||||
resource: BitmapPaletteWrapper,
|
||||
transition: Transition<in BitmapPaletteWrapper>?
|
||||
transition: Transition<in BitmapPaletteWrapper>?,
|
||||
) {
|
||||
val palette = resource.palette
|
||||
update(
|
||||
|
@ -150,25 +142,27 @@ class AppWidgetCircle : BaseAppWidget() {
|
|||
private fun update(bitmap: Bitmap?, color: Int) {
|
||||
// Set correct drawable for pause state
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service, playPauseRes, color
|
||||
)
|
||||
)
|
||||
R.id.button_toggle_play_pause,
|
||||
service.getTintedDrawable(
|
||||
playPauseRes, color
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
// Set favorite button drawables
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_favorite, ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service, favoriteRes, color
|
||||
)
|
||||
)
|
||||
R.id.button_toggle_favorite,
|
||||
service.getTintedDrawable(
|
||||
favoriteRes, color
|
||||
).toBitmap()
|
||||
)
|
||||
if (bitmap != null) {
|
||||
appWidgetView.setImageViewBitmap(R.id.image, bitmap)
|
||||
}
|
||||
|
||||
pushUpdate(service, appWidgetIds, appWidgetView)
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,11 +23,13 @@ import android.graphics.Color
|
|||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
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.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.palette.BitmapPaletteWrapper
|
||||
|
@ -35,11 +37,9 @@ import code.name.monkey.retromusic.service.MusicService
|
|||
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
|
||||
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.ImageUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.target.SimpleTarget
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
|
||||
|
@ -57,33 +57,27 @@ class AppWidgetClassic : BaseAppWidget() {
|
|||
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next,
|
||||
createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_skip_next,
|
||||
MaterialValueHelper.getSecondaryTextColor(context, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev,
|
||||
createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_skip_previous,
|
||||
MaterialValueHelper.getSecondaryTextColor(context, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause,
|
||||
createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_play_arrow_white_32dp,
|
||||
MaterialValueHelper.getSecondaryTextColor(context, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
linkButtons(context, appWidgetView)
|
||||
|
@ -129,10 +123,10 @@ class AppWidgetClassic : BaseAppWidget() {
|
|||
.load(RetroGlideExtension.getSongModel(song))
|
||||
//.checkIgnoreMediaStore()
|
||||
.centerCrop()
|
||||
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
|
||||
.into(object : CustomTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
|
||||
override fun onResourceReady(
|
||||
resource: BitmapPaletteWrapper,
|
||||
transition: Transition<in BitmapPaletteWrapper>?
|
||||
transition: Transition<in BitmapPaletteWrapper>?,
|
||||
) {
|
||||
val palette = resource.palette
|
||||
update(
|
||||
|
@ -153,44 +147,37 @@ class AppWidgetClassic : BaseAppWidget() {
|
|||
update(null, Color.WHITE)
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {}
|
||||
|
||||
private fun update(bitmap: Bitmap?, color: Int) {
|
||||
// Set correct drawable for pause state
|
||||
val playPauseRes =
|
||||
if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause,
|
||||
ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
service.getTintedDrawable(
|
||||
playPauseRes,
|
||||
color
|
||||
)
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
// Set prev/next button drawables
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next,
|
||||
ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
service.getTintedDrawable(
|
||||
R.drawable.ic_skip_next,
|
||||
color
|
||||
)
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev,
|
||||
ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
service.getTintedDrawable(
|
||||
R.drawable.ic_skip_previous,
|
||||
color
|
||||
)
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
val image = getAlbumArtDrawable(service.resources, bitmap)
|
||||
val image = getAlbumArtDrawable(service, bitmap)
|
||||
val roundedBitmap =
|
||||
createRoundedBitmap(
|
||||
image,
|
||||
|
|
|
@ -22,11 +22,13 @@ import android.graphics.Bitmap
|
|||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
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.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.palette.BitmapPaletteWrapper
|
||||
|
@ -35,11 +37,9 @@ import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
|
|||
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.DensityUtil
|
||||
import code.name.monkey.retromusic.util.ImageUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.target.SimpleTarget
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
|
||||
|
@ -57,31 +57,25 @@ class AppWidgetMD3 : BaseAppWidget() {
|
|||
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
|
||||
val secondaryColor = MaterialValueHelper.getSecondaryTextColor(context, true)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
R.id.button_next,
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_skip_next,
|
||||
secondaryColor
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
R.id.button_prev,
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_skip_previous,
|
||||
secondaryColor
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
R.id.button_toggle_play_pause,
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_play_arrow_white_32dp,
|
||||
secondaryColor
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
linkButtons(context, appWidgetView)
|
||||
|
@ -110,33 +104,27 @@ class AppWidgetMD3 : BaseAppWidget() {
|
|||
val playPauseRes =
|
||||
if (isPlaying) R.drawable.ic_pause else R.drawable.ic_play_arrow_white_32dp
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_toggle_play_pause,
|
||||
service.getTintedDrawable(
|
||||
playPauseRes,
|
||||
MaterialValueHelper.getSecondaryTextColor(service, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
// Set prev/next button drawables
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_next,
|
||||
service.getTintedDrawable(
|
||||
R.drawable.ic_skip_next,
|
||||
MaterialValueHelper.getSecondaryTextColor(service, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service,
|
||||
R.id.button_prev,
|
||||
service.getTintedDrawable(
|
||||
R.drawable.ic_skip_previous,
|
||||
MaterialValueHelper.getSecondaryTextColor(service, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
// Link actions buttons to intents
|
||||
|
@ -159,10 +147,10 @@ class AppWidgetMD3 : BaseAppWidget() {
|
|||
target = GlideApp.with(service).asBitmapPalette().songCoverOptions(song)
|
||||
.load(RetroGlideExtension.getSongModel(song))
|
||||
.centerCrop()
|
||||
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
|
||||
.into(object : CustomTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
|
||||
override fun onResourceReady(
|
||||
resource: BitmapPaletteWrapper,
|
||||
transition: Transition<in BitmapPaletteWrapper>?
|
||||
transition: Transition<in BitmapPaletteWrapper>?,
|
||||
) {
|
||||
val palette = resource.palette
|
||||
update(
|
||||
|
@ -181,33 +169,26 @@ class AppWidgetMD3 : BaseAppWidget() {
|
|||
update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {}
|
||||
|
||||
private fun update(bitmap: Bitmap?, color: Int) {
|
||||
// Set correct drawable for pause state
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service, playPauseRes, color
|
||||
)
|
||||
)
|
||||
R.id.button_toggle_play_pause,
|
||||
service.getTintedDrawable(playPauseRes, color).toBitmap()
|
||||
)
|
||||
|
||||
// Set prev/next button drawables
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service, R.drawable.ic_skip_next, color
|
||||
)
|
||||
)
|
||||
R.id.button_next,
|
||||
service.getTintedDrawable(R.drawable.ic_skip_next, color).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, ImageUtil.createBitmap(
|
||||
ImageUtil.getTintedVectorDrawable(
|
||||
service, R.drawable.ic_skip_previous, color
|
||||
)
|
||||
)
|
||||
R.id.button_prev,
|
||||
service.getTintedDrawable(R.drawable.ic_skip_previous, color).toBitmap()
|
||||
)
|
||||
|
||||
val image = getAlbumArtDrawable(service.resources, bitmap)
|
||||
val image = getAlbumArtDrawable(service, bitmap)
|
||||
val roundedBitmap = createRoundedBitmap(
|
||||
image,
|
||||
imageSize,
|
||||
|
|
|
@ -22,11 +22,13 @@ import android.graphics.Bitmap
|
|||
import android.graphics.drawable.Drawable
|
||||
import android.view.View
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
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.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.palette.BitmapPaletteWrapper
|
||||
|
@ -35,9 +37,8 @@ import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
|
|||
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.RetroUtil
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.target.SimpleTarget
|
||||
import com.bumptech.glide.request.target.CustomTarget
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
|
||||
|
@ -55,33 +56,26 @@ class AppWidgetSmall : BaseAppWidget() {
|
|||
appWidgetView.setImageViewResource(R.id.image, R.drawable.default_audio_art)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next,
|
||||
createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_skip_next,
|
||||
MaterialValueHelper.getSecondaryTextColor(context, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev,
|
||||
createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_skip_previous,
|
||||
MaterialValueHelper.getSecondaryTextColor(context, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause,
|
||||
createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context,
|
||||
|
||||
context.getTintedDrawable(
|
||||
R.drawable.ic_play_arrow_white_32dp,
|
||||
MaterialValueHelper.getSecondaryTextColor(context, true)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
linkButtons(context, appWidgetView)
|
||||
|
@ -132,10 +126,10 @@ class AppWidgetSmall : BaseAppWidget() {
|
|||
//.checkIgnoreMediaStore()
|
||||
.load(RetroGlideExtension.getSongModel(song))
|
||||
.centerCrop()
|
||||
.into(object : SimpleTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
|
||||
.into(object : CustomTarget<BitmapPaletteWrapper>(imageSize, imageSize) {
|
||||
override fun onResourceReady(
|
||||
resource: BitmapPaletteWrapper,
|
||||
transition: Transition<in BitmapPaletteWrapper>?
|
||||
transition: Transition<in BitmapPaletteWrapper>?,
|
||||
) {
|
||||
val palette = resource.palette
|
||||
update(
|
||||
|
@ -154,35 +148,30 @@ class AppWidgetSmall : BaseAppWidget() {
|
|||
update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
|
||||
}
|
||||
|
||||
override fun onLoadCleared(placeholder: Drawable?) {
|
||||
update(null, MaterialValueHelper.getSecondaryTextColor(service, true))
|
||||
}
|
||||
|
||||
private fun update(bitmap: Bitmap?, color: Int) {
|
||||
// Set correct drawable for pause state
|
||||
val playPauseRes = if (isPlaying) R.drawable.ic_pause
|
||||
else R.drawable.ic_play_arrow_white_32dp
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service, playPauseRes, color
|
||||
), 1f
|
||||
)
|
||||
R.id.button_toggle_play_pause,
|
||||
service.getTintedDrawable(playPauseRes, color).toBitmap()
|
||||
)
|
||||
|
||||
// Set prev/next button drawables
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service, R.drawable.ic_skip_next, color
|
||||
), 1f
|
||||
)
|
||||
R.id.button_next,
|
||||
service.getTintedDrawable(R.drawable.ic_skip_next, color).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
service, R.drawable.ic_skip_previous, color
|
||||
), 1f
|
||||
)
|
||||
R.id.button_prev,
|
||||
service.getTintedDrawable(R.drawable.ic_skip_previous, color).toBitmap()
|
||||
)
|
||||
|
||||
val image = getAlbumArtDrawable(service.resources, bitmap)
|
||||
val image = getAlbumArtDrawable(service, bitmap)
|
||||
val roundedBitmap = createRoundedBitmap(
|
||||
image, imageSize, imageSize, cardRadius, 0f, 0f, 0f
|
||||
)
|
||||
|
|
|
@ -21,48 +21,41 @@ import android.content.Intent
|
|||
import android.view.View
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||
import code.name.monkey.retromusic.App
|
||||
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.service.MusicService
|
||||
import code.name.monkey.retromusic.service.MusicService.Companion.ACTION_REWIND
|
||||
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.RetroUtil
|
||||
|
||||
class AppWidgetText : BaseAppWidget() {
|
||||
override fun defaultAppWidget(context: Context, appWidgetIds: IntArray) {
|
||||
val appWidgetView = RemoteViews(context.packageName, R.layout.app_widget_text)
|
||||
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context, R.drawable.ic_skip_next, ContextCompat.getColor(
|
||||
R.id.button_next,
|
||||
context.getTintedDrawable(R.drawable.ic_skip_next, ContextCompat.getColor(
|
||||
context, R.color.md_white_1000
|
||||
)
|
||||
), 1f
|
||||
)
|
||||
)).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context, R.drawable.ic_skip_previous, ContextCompat.getColor(
|
||||
R.id.button_prev,
|
||||
context.getTintedDrawable(R.drawable.ic_skip_previous, ContextCompat.getColor(
|
||||
context, R.color.md_white_1000
|
||||
)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
context, R.drawable.ic_play_arrow_white_32dp, ContextCompat.getColor(
|
||||
R.id.button_toggle_play_pause,
|
||||
context.getTintedDrawable(R.drawable.ic_play_arrow_white_32dp, ContextCompat.getColor(
|
||||
context, R.color.md_white_1000
|
||||
)
|
||||
), 1f
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
appWidgetView.setTextColor(
|
||||
|
@ -132,35 +125,29 @@ class AppWidgetText : BaseAppWidget() {
|
|||
val playPauseRes = if (isPlaying) R.drawable.ic_pause
|
||||
else R.drawable.ic_play_arrow_white_32dp
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_toggle_play_pause, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
App.getContext(), playPauseRes, ContextCompat.getColor(
|
||||
App.getContext(), R.color.md_white_1000
|
||||
)
|
||||
), 1f
|
||||
)
|
||||
R.id.button_toggle_play_pause,
|
||||
service.getTintedDrawable(playPauseRes, ContextCompat.getColor(
|
||||
service, R.color.md_white_1000)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_next, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
App.getContext(),
|
||||
R.id.button_next,
|
||||
service.getTintedDrawable(
|
||||
R.drawable.ic_skip_next,
|
||||
ContextCompat.getColor(
|
||||
App.getContext(), R.color.md_white_1000
|
||||
)
|
||||
), 1f
|
||||
service,
|
||||
R.color.md_white_1000
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
appWidgetView.setImageViewBitmap(
|
||||
R.id.button_prev, createBitmap(
|
||||
RetroUtil.getTintedVectorDrawable(
|
||||
App.getContext(),
|
||||
R.id.button_prev,
|
||||
service.getTintedDrawable(
|
||||
R.drawable.ic_skip_previous,
|
||||
ContextCompat.getColor(
|
||||
App.getContext(), R.color.md_white_1000
|
||||
)
|
||||
), 1f
|
||||
service, R.color.md_white_1000
|
||||
)
|
||||
).toBitmap()
|
||||
)
|
||||
|
||||
pushUpdate(service.applicationContext, appWidgetIds, appWidgetView)
|
||||
|
|
|
@ -20,16 +20,12 @@ import android.appwidget.AppWidgetProvider
|
|||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.Resources
|
||||
import android.graphics.*
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.widget.RemoteViews
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.applyCanvas
|
||||
import androidx.core.graphics.createBitmap
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.service.MusicService
|
||||
|
@ -116,11 +112,11 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
|||
|
||||
abstract fun performUpdate(service: MusicService, appWidgetIds: IntArray?)
|
||||
|
||||
protected fun getAlbumArtDrawable(resources: Resources, bitmap: Bitmap?): Drawable {
|
||||
protected fun getAlbumArtDrawable(context: Context, bitmap: Bitmap?): Drawable {
|
||||
return if (bitmap == null) {
|
||||
ContextCompat.getDrawable(App.getContext(), R.drawable.default_audio_art)!!
|
||||
ContextCompat.getDrawable(context, R.drawable.default_audio_art)!!
|
||||
} else {
|
||||
BitmapDrawable(resources, bitmap)
|
||||
BitmapDrawable(context.resources, bitmap)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,16 +167,6 @@ abstract class BaseAppWidget : AppWidgetProvider() {
|
|||
return rounded
|
||||
}
|
||||
|
||||
fun createBitmap(drawable: Drawable, sizeMultiplier: Float): Bitmap {
|
||||
return createBitmap(
|
||||
(drawable.intrinsicWidth * sizeMultiplier).toInt(),
|
||||
(drawable.intrinsicHeight * sizeMultiplier).toInt(),
|
||||
).applyCanvas {
|
||||
drawable.setBounds(0, 0, this.width, this.height)
|
||||
drawable.draw(this)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun composeRoundedRectPath(
|
||||
rect: RectF,
|
||||
tl: Float,
|
||||
|
|
|
@ -4,8 +4,9 @@ import android.content.Context
|
|||
import android.net.Uri
|
||||
import android.support.v4.media.MediaBrowserCompat
|
||||
import android.support.v4.media.MediaDescriptionCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import androidx.core.os.bundleOf
|
||||
import code.name.monkey.retromusic.util.ImageUtil
|
||||
|
||||
|
||||
internal object AutoMediaItem {
|
||||
|
@ -13,7 +14,7 @@ internal object AutoMediaItem {
|
|||
return Builder(context)
|
||||
}
|
||||
|
||||
internal class Builder(val mContext: Context) {
|
||||
internal class Builder(private val mContext: Context) {
|
||||
private var mBuilder: MediaDescriptionCompat.Builder?
|
||||
private var mFlags = 0
|
||||
fun path(fullPath: String): Builder {
|
||||
|
@ -42,13 +43,11 @@ internal object AutoMediaItem {
|
|||
|
||||
fun icon(iconDrawableId: Int): Builder {
|
||||
mBuilder?.setIconBitmap(
|
||||
ImageUtil.createBitmap(
|
||||
ImageUtil.getVectorDrawable(
|
||||
ResourcesCompat.getDrawable(
|
||||
mContext.resources,
|
||||
iconDrawableId,
|
||||
mContext.theme
|
||||
)
|
||||
)
|
||||
)?.toBitmap()
|
||||
)
|
||||
return this
|
||||
}
|
||||
|
|
|
@ -79,6 +79,5 @@ object CastHelper {
|
|||
setMetadata(musicMetadata)
|
||||
setStreamDuration(song.duration)
|
||||
}.build()
|
||||
|
||||
}
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
@file:Suppress("unused")
|
||||
|
||||
package code.name.monkey.retromusic.cast
|
||||
|
||||
import android.content.Context
|
||||
|
|
|
@ -3,20 +3,12 @@ package code.name.monkey.retromusic.cast
|
|||
import com.google.android.gms.cast.framework.CastSession
|
||||
import com.google.android.gms.cast.framework.SessionManagerListener
|
||||
|
||||
interface RetroSessionManager : SessionManagerListener<CastSession> {
|
||||
override fun onSessionResuming(p0: CastSession, p1: String) {
|
||||
interface RetroSessionManagerListener : SessionManagerListener<CastSession> {
|
||||
override fun onSessionResuming(p0: CastSession, p1: String) {}
|
||||
|
||||
}
|
||||
override fun onSessionStartFailed(p0: CastSession, p1: Int) {}
|
||||
|
||||
override fun onSessionStartFailed(p0: CastSession, p1: Int) {
|
||||
override fun onSessionResumeFailed(p0: CastSession, p1: Int) {}
|
||||
|
||||
}
|
||||
|
||||
override fun onSessionResumeFailed(p0: CastSession, p1: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun onSessionEnding(p0: CastSession) {
|
||||
|
||||
}
|
||||
override fun onSessionEnding(castSession: CastSession) {}
|
||||
}
|
|
@ -17,24 +17,11 @@ class RetroWebServer(val context: Context) : NanoHTTPD(SERVER_PORT) {
|
|||
const val PART_COVER_ART = "coverart"
|
||||
const val PART_SONG = "song"
|
||||
const val PARAM_ID = "id"
|
||||
private var mRetroWebServer: RetroWebServer? = null
|
||||
fun getInstance(context: Context): RetroWebServer {
|
||||
if (mRetroWebServer == null) {
|
||||
mRetroWebServer = RetroWebServer(context)
|
||||
}
|
||||
return mRetroWebServer!!
|
||||
}
|
||||
}
|
||||
|
||||
override fun serve(
|
||||
uri: String?,
|
||||
method: Method?,
|
||||
headers: MutableMap<String, String>?,
|
||||
parms: MutableMap<String, String>?,
|
||||
files: MutableMap<String, String>?
|
||||
): Response {
|
||||
if (uri?.contains(PART_COVER_ART) == true) {
|
||||
val albumId = parms?.get(PARAM_ID) ?: return errorResponse()
|
||||
override fun serve(session: IHTTPSession?): Response {
|
||||
if (session?.uri?.contains(PART_COVER_ART) == true) {
|
||||
val albumId = session.parameters?.get(PARAM_ID)?.get(0) ?: return errorResponse()
|
||||
val albumArtUri = MusicUtil.getMediaStoreAlbumCoverUri(albumId.toLong())
|
||||
val fis: InputStream?
|
||||
try {
|
||||
|
@ -43,12 +30,12 @@ class RetroWebServer(val context: Context) : NanoHTTPD(SERVER_PORT) {
|
|||
return errorResponse()
|
||||
}
|
||||
return newChunkedResponse(Status.OK, MIME_TYPE_IMAGE, fis)
|
||||
} else if (uri?.contains(PART_SONG) == true) {
|
||||
val songId = parms?.get(PARAM_ID) ?: return errorResponse()
|
||||
} else if (session?.uri?.contains(PART_SONG) == true) {
|
||||
val songId = session.parameters?.get(PARAM_ID)?.get(0) ?: return errorResponse()
|
||||
val songUri = MusicUtil.getSongFileUri(songId.toLong())
|
||||
val songPath = MusicUtil.getSongFilePath(context, songUri)
|
||||
val song = File(songPath)
|
||||
return serveFile(headers!!, song, MIME_TYPE_AUDIO)
|
||||
return serveFile(session.headers!!, song, MIME_TYPE_AUDIO)
|
||||
}
|
||||
return newFixedLengthResponse(Status.NOT_FOUND, MIME_PLAINTEXT, "Not Found")
|
||||
}
|
||||
|
@ -120,7 +107,7 @@ class RetroWebServer(val context: Context) : NanoHTTPD(SERVER_PORT) {
|
|||
} else {
|
||||
res = newFixedLengthResponse(
|
||||
Status.OK, mime,
|
||||
FileInputStream(file), file.length()
|
||||
file.inputStream(), file.length()
|
||||
)
|
||||
res.addHeader("Accept-Ranges", "bytes")
|
||||
res.addHeader("Content-Length", "" + fileLen)
|
||||
|
|
|
@ -16,7 +16,6 @@ package code.name.monkey.retromusic.dialogs
|
|||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import code.name.monkey.retromusic.EXTRA_PLAYLISTS
|
||||
|
@ -50,12 +49,6 @@ class AddToPlaylistDialog : DialogFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun playlistAdapter(playlists: List<String>): ArrayAdapter<String> {
|
||||
val adapter = ArrayAdapter<String>(requireContext(), R.layout.item_simple_text, R.id.title)
|
||||
adapter.addAll(playlists)
|
||||
return adapter
|
||||
}
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val playlistEntities = extraNotNull<List<PlaylistEntity>>(EXTRA_PLAYLISTS).value
|
||||
val songs = extraNotNull<List<Song>>(EXTRA_SONG).value
|
||||
|
@ -65,18 +58,17 @@ class AddToPlaylistDialog : DialogFragment() {
|
|||
playlistNames.add(entity.playlistName)
|
||||
}
|
||||
return materialDialog(R.string.add_playlist_title)
|
||||
.setAdapter(
|
||||
playlistAdapter(playlistNames)
|
||||
) { dialog, which ->
|
||||
.setItems(playlistNames.toTypedArray()) { dialog, which->
|
||||
if (which == 0) {
|
||||
showCreateDialog(songs)
|
||||
} else {
|
||||
libraryViewModel.addToPlaylist(playlistNames[which], songs)
|
||||
libraryViewModel.addToPlaylist(requireContext(), playlistNames[which], songs)
|
||||
}
|
||||
dialog.dismiss()
|
||||
}
|
||||
.setNegativeButton(R.string.action_cancel, null)
|
||||
.create().colorButtons()
|
||||
.create()
|
||||
.colorButtons()
|
||||
}
|
||||
|
||||
private fun showCreateDialog(songs: List<Song>) {
|
||||
|
|
|
@ -4,19 +4,19 @@ import android.Manifest
|
|||
import android.app.Dialog
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.extensions.materialDialog
|
||||
import code.name.monkey.retromusic.util.getExternalStorageDirectory
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.list.listItems
|
||||
import com.afollestad.materialdialogs.list.updateListItems
|
||||
import java.io.File
|
||||
|
||||
class BlacklistFolderChooserDialog : DialogFragment() {
|
||||
private var initialPath: String = Environment.getExternalStorageDirectory().absolutePath
|
||||
private var initialPath: String = getExternalStorageDirectory().absolutePath
|
||||
private var parentFolder: File? = null
|
||||
private var parentContents: Array<File>? = null
|
||||
private var canGoUp = false
|
||||
|
@ -97,7 +97,7 @@ class BlacklistFolderChooserDialog : DialogFragment() {
|
|||
parentFolder = parentContents?.getOrNull(if (canGoUp) i - 1 else i)
|
||||
canGoUp = true
|
||||
if (parentFolder?.absolutePath == "/storage/emulated") {
|
||||
parentFolder = Environment.getExternalStorageDirectory()
|
||||
parentFolder = getExternalStorageDirectory()
|
||||
}
|
||||
}
|
||||
reload()
|
||||
|
|
|
@ -64,11 +64,12 @@ class CreatePlaylistDialog : DialogFragment() {
|
|||
) { _, _ ->
|
||||
val playlistName = playlistView.text.toString()
|
||||
if (!TextUtils.isEmpty(playlistName)) {
|
||||
libraryViewModel.addToPlaylist(playlistName, songs)
|
||||
libraryViewModel.addToPlaylist(requireContext(), playlistName, songs)
|
||||
} else {
|
||||
playlistContainer.error = "Playlist name can't be empty"
|
||||
}
|
||||
}
|
||||
.setNegativeButton(R.string.action_cancel, null)
|
||||
.create()
|
||||
.colorButtons()
|
||||
}
|
||||
|
|
|
@ -16,7 +16,6 @@ package code.name.monkey.retromusic.dialogs
|
|||
|
||||
import android.app.Dialog
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import code.name.monkey.retromusic.EXTRA_PLAYLIST_ID
|
||||
|
@ -48,7 +47,7 @@ class RenamePlaylistDialog : DialogFragment() {
|
|||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val playlistEntity = extraNotNull<PlaylistEntity>(EXTRA_PLAYLIST_ID).value
|
||||
val layout = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_playlist, null)
|
||||
val layout = layoutInflater.inflate(R.layout.dialog_playlist, null)
|
||||
val inputEditText: TextInputEditText = layout.findViewById(R.id.actionNewPlaylist)
|
||||
val nameContainer: TextInputLayout = layout.findViewById(R.id.actionNewPlaylistContainer)
|
||||
nameContainer.accentColor()
|
||||
|
|
|
@ -22,14 +22,10 @@ import androidx.core.os.bundleOf
|
|||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import code.name.monkey.appthemehelper.util.VersionUtils
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.EXTRA_PLAYLIST
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.db.PlaylistWithSongs
|
||||
import code.name.monkey.retromusic.extensions.colorButtons
|
||||
import code.name.monkey.retromusic.extensions.createNewFile
|
||||
import code.name.monkey.retromusic.extensions.extraNotNull
|
||||
import code.name.monkey.retromusic.extensions.materialDialog
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.helper.M3UWriter
|
||||
import code.name.monkey.retromusic.util.PlaylistsUtil
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
@ -64,25 +60,19 @@ class SavePlaylistDialog : DialogFragment() {
|
|||
playlistWithSongs
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
String.format(
|
||||
requireContext().getString(R.string.saved_playlist_to),
|
||||
data?.lastPathSegment
|
||||
),
|
||||
showToast(
|
||||
requireContext().getString(R.string.saved_playlist_to,
|
||||
data?.lastPathSegment),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"Something went wrong : " + e.message,
|
||||
Toast.LENGTH_SHORT
|
||||
showToast(
|
||||
"Something went wrong : " + e.message
|
||||
)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -95,11 +85,10 @@ class SavePlaylistDialog : DialogFragment() {
|
|||
) { _, _ ->
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
String.format(App.getContext().getString(R.string.saved_playlist_to), file),
|
||||
showToast(
|
||||
getString(R.string.saved_playlist_to, file),
|
||||
Toast.LENGTH_LONG
|
||||
).show()
|
||||
)
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,60 +19,50 @@ import android.content.Context
|
|||
import android.os.Bundle
|
||||
import android.text.Spanned
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.NonNull
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import code.name.monkey.retromusic.EXTRA_SONG
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.DialogFileDetailsBinding
|
||||
import code.name.monkey.retromusic.extensions.colorButtons
|
||||
import code.name.monkey.retromusic.extensions.materialDialog
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.MusicUtil
|
||||
import org.jaudiotagger.audio.AudioFileIO
|
||||
import org.jaudiotagger.audio.exceptions.CannotReadException
|
||||
import org.jaudiotagger.audio.exceptions.InvalidAudioFrameException
|
||||
import org.jaudiotagger.audio.exceptions.ReadOnlyFileException
|
||||
import org.jaudiotagger.tag.TagException
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
class SongDetailDialog : DialogFragment() {
|
||||
|
||||
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||
val context: Context = requireContext()
|
||||
val dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_file_details, null)
|
||||
val binding = DialogFileDetailsBinding.inflate(layoutInflater)
|
||||
|
||||
val song = requireArguments().getParcelable<Song>(EXTRA_SONG)
|
||||
val fileName: TextView = dialogView.findViewById(R.id.fileName)
|
||||
val filePath: TextView = dialogView.findViewById(R.id.filePath)
|
||||
val fileSize: TextView = dialogView.findViewById(R.id.fileSize)
|
||||
val dateModified: TextView = dialogView.findViewById(R.id.dateModified)
|
||||
val fileFormat: TextView = dialogView.findViewById(R.id.fileFormat)
|
||||
val trackLength: TextView = dialogView.findViewById(R.id.trackLength)
|
||||
val bitRate: TextView = dialogView.findViewById(R.id.bitrate)
|
||||
val samplingRate: TextView = dialogView.findViewById(R.id.samplingRate)
|
||||
|
||||
with(binding) {
|
||||
fileName.text = makeTextWithTitle(context, R.string.label_file_name, "-")
|
||||
filePath.text = makeTextWithTitle(context, R.string.label_file_path, "-")
|
||||
fileSize.text = makeTextWithTitle(context, R.string.label_file_size, "-")
|
||||
fileFormat.text = makeTextWithTitle(context, R.string.label_file_format, "-")
|
||||
trackLength.text = makeTextWithTitle(context, R.string.label_track_length, "-")
|
||||
bitRate.text = makeTextWithTitle(context, R.string.label_bit_rate, "-")
|
||||
bitrate.text = makeTextWithTitle(context, R.string.label_bit_rate, "-")
|
||||
samplingRate.text = makeTextWithTitle(context, R.string.label_sampling_rate, "-")
|
||||
}
|
||||
|
||||
if (song != null) {
|
||||
val songFile = File(song.data)
|
||||
if (songFile.exists()) {
|
||||
fileName.text = makeTextWithTitle(context, R.string.label_file_name, songFile.name)
|
||||
filePath.text =
|
||||
binding.fileName.text =
|
||||
makeTextWithTitle(context, R.string.label_file_name, songFile.name)
|
||||
binding.filePath.text =
|
||||
makeTextWithTitle(context, R.string.label_file_path, songFile.absolutePath)
|
||||
|
||||
dateModified.text = makeTextWithTitle(context, R.string.label_last_modified,
|
||||
MusicUtil.getDateModifiedString(songFile.lastModified()))
|
||||
binding.dateModified.text = makeTextWithTitle(
|
||||
context, R.string.label_last_modified,
|
||||
MusicUtil.getDateModifiedString(songFile.lastModified())
|
||||
)
|
||||
|
||||
fileSize.text =
|
||||
binding.fileSize.text =
|
||||
makeTextWithTitle(
|
||||
context,
|
||||
R.string.label_file_size,
|
||||
|
@ -82,56 +72,28 @@ class SongDetailDialog : DialogFragment() {
|
|||
val audioFile = AudioFileIO.read(songFile)
|
||||
val audioHeader = audioFile.audioHeader
|
||||
|
||||
fileFormat.text =
|
||||
binding.fileFormat.text =
|
||||
makeTextWithTitle(context, R.string.label_file_format, audioHeader.format)
|
||||
trackLength.text = makeTextWithTitle(
|
||||
binding.trackLength.text = makeTextWithTitle(
|
||||
context,
|
||||
R.string.label_track_length,
|
||||
MusicUtil.getReadableDurationString((audioHeader.trackLength * 1000).toLong())
|
||||
)
|
||||
bitRate.text = makeTextWithTitle(
|
||||
binding.bitrate.text = makeTextWithTitle(
|
||||
context,
|
||||
R.string.label_bit_rate,
|
||||
audioHeader.bitRate + " kb/s"
|
||||
)
|
||||
samplingRate.text =
|
||||
binding.samplingRate.text =
|
||||
makeTextWithTitle(
|
||||
context,
|
||||
R.string.label_sampling_rate,
|
||||
audioHeader.sampleRate + " Hz"
|
||||
)
|
||||
} catch (@NonNull e: CannotReadException) {
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "error while reading the song file", e)
|
||||
// fallback
|
||||
trackLength.text = makeTextWithTitle(
|
||||
context,
|
||||
R.string.label_track_length,
|
||||
MusicUtil.getReadableDurationString(song.duration)
|
||||
)
|
||||
} catch (@NonNull e: IOException) {
|
||||
Log.e(TAG, "error while reading the song file", e)
|
||||
trackLength.text = makeTextWithTitle(
|
||||
context,
|
||||
R.string.label_track_length,
|
||||
MusicUtil.getReadableDurationString(song.duration)
|
||||
)
|
||||
} catch (@NonNull e: TagException) {
|
||||
Log.e(TAG, "error while reading the song file", e)
|
||||
trackLength.text = makeTextWithTitle(
|
||||
context,
|
||||
R.string.label_track_length,
|
||||
MusicUtil.getReadableDurationString(song.duration)
|
||||
)
|
||||
} catch (@NonNull e: ReadOnlyFileException) {
|
||||
Log.e(TAG, "error while reading the song file", e)
|
||||
trackLength.text = makeTextWithTitle(
|
||||
context,
|
||||
R.string.label_track_length,
|
||||
MusicUtil.getReadableDurationString(song.duration)
|
||||
)
|
||||
} catch (@NonNull e: InvalidAudioFrameException) {
|
||||
Log.e(TAG, "error while reading the song file", e)
|
||||
trackLength.text = makeTextWithTitle(
|
||||
binding.trackLength.text = makeTextWithTitle(
|
||||
context,
|
||||
R.string.label_track_length,
|
||||
MusicUtil.getReadableDurationString(song.duration)
|
||||
|
@ -139,8 +101,9 @@ class SongDetailDialog : DialogFragment() {
|
|||
}
|
||||
} else {
|
||||
// fallback
|
||||
fileName.text = makeTextWithTitle(context, R.string.label_file_name, song.title)
|
||||
trackLength.text = makeTextWithTitle(
|
||||
binding.fileName.text =
|
||||
makeTextWithTitle(context, R.string.label_file_name, song.title)
|
||||
binding.trackLength.text = makeTextWithTitle(
|
||||
context,
|
||||
R.string.label_track_length,
|
||||
MusicUtil.getReadableDurationString(song.duration)
|
||||
|
@ -149,7 +112,7 @@ class SongDetailDialog : DialogFragment() {
|
|||
}
|
||||
return materialDialog(R.string.action_details)
|
||||
.setPositiveButton(android.R.string.ok, null)
|
||||
.setView(dialogView)
|
||||
.setView(binding.root)
|
||||
.create()
|
||||
.colorButtons()
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ class SongShareDialog : DialogFragment() {
|
|||
) { _, which ->
|
||||
withAction(which, song, listening)
|
||||
}
|
||||
.setNegativeButton(R.string.action_cancel, null)
|
||||
.create()
|
||||
.colorButtons()
|
||||
}
|
||||
|
|
|
@ -6,7 +6,9 @@ import android.os.Build
|
|||
import android.view.View
|
||||
import android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
|
||||
import android.view.WindowManager
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.view.*
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
|
@ -222,3 +224,12 @@ fun AppCompatActivity.setStatusBarColorPreMarshmallow(color: Int) {
|
|||
window.statusBarColor = ColorUtil.darkenColor(color)
|
||||
}
|
||||
}
|
||||
|
||||
fun AppCompatActivity.hideSoftKeyboard() {
|
||||
val currentFocus: View? = currentFocus
|
||||
if (currentFocus != null) {
|
||||
val inputMethodManager =
|
||||
getSystemService<InputMethodManager>()
|
||||
inputMethodManager?.hideSoftInputFromWindow(currentFocus.windowToken, 0)
|
||||
}
|
||||
}
|
|
@ -36,7 +36,6 @@ import code.name.monkey.appthemehelper.ThemeStore
|
|||
import code.name.monkey.appthemehelper.util.ATHUtil
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.MaterialValueHelper
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil.materialYou
|
||||
import com.google.android.material.button.MaterialButton
|
||||
|
@ -131,12 +130,12 @@ fun Slider.accent() {
|
|||
|
||||
fun Button.accentTextColor() {
|
||||
if (materialYou) return
|
||||
setTextColor(ThemeStore.accentColor(App.getContext()))
|
||||
setTextColor(context.accentColor())
|
||||
}
|
||||
|
||||
fun MaterialButton.accentBackgroundColor() {
|
||||
if (materialYou) return
|
||||
backgroundTintList = ColorStateList.valueOf(ThemeStore.accentColor(App.getContext()))
|
||||
backgroundTintList = ColorStateList.valueOf(context.accentColor())
|
||||
}
|
||||
|
||||
fun MaterialButton.accentOutlineColor() {
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package code.name.monkey.retromusic.extensions
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.ColorInt
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.core.content.ContextCompat
|
||||
|
||||
fun Context.showToast(@StringRes stringRes: Int, duration: Int = Toast.LENGTH_SHORT) {
|
||||
showToast(getString(stringRes), duration)
|
||||
}
|
||||
|
||||
fun Context.showToast(message: String, duration: Int = Toast.LENGTH_SHORT) {
|
||||
Toast.makeText(this, message, duration).show()
|
||||
}
|
||||
|
||||
val Context.isLandscape: Boolean get() = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||
|
||||
val Context.isTablet: Boolean get() = resources.configuration.smallestScreenWidthDp >= 600
|
||||
|
||||
fun Context.getTintedDrawable(@DrawableRes id: Int, @ColorInt color: Int): Drawable {
|
||||
return ContextCompat.getDrawable(this, id)?.tint(color)!!
|
||||
}
|
|
@ -15,17 +15,23 @@
|
|||
package code.name.monkey.retromusic.extensions
|
||||
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.Fragment
|
||||
import code.name.monkey.retromusic.BuildConfig
|
||||
import code.name.monkey.retromusic.R
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
|
||||
fun DialogFragment.materialDialog(title: Int): MaterialAlertDialogBuilder {
|
||||
return MaterialAlertDialogBuilder(
|
||||
fun Fragment.materialDialog(title: Int): MaterialAlertDialogBuilder {
|
||||
return if (BuildConfig.DEBUG) {
|
||||
MaterialAlertDialogBuilder(
|
||||
requireContext(),
|
||||
R.style.MaterialAlertDialogTheme
|
||||
).setTitle(title)
|
||||
)
|
||||
} else {
|
||||
MaterialAlertDialogBuilder(
|
||||
requireContext()
|
||||
)
|
||||
}.setTitle(title)
|
||||
}
|
||||
|
||||
fun AlertDialog.colorButtons(): AlertDialog {
|
||||
|
|
|
@ -22,11 +22,12 @@ import android.graphics.drawable.BitmapDrawable
|
|||
import android.graphics.drawable.Drawable
|
||||
import androidx.annotation.DimenRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
|
||||
fun Context.scaledDrawableResources(
|
||||
@DrawableRes id: Int,
|
||||
@DimenRes width: Int,
|
||||
@DimenRes height: Int
|
||||
@DimenRes height: Int,
|
||||
): Drawable {
|
||||
val w = resources.getDimension(width).toInt()
|
||||
val h = resources.getDimension(height).toInt()
|
||||
|
@ -39,6 +40,10 @@ fun Context.scaledDrawable(@DrawableRes id: Int, width: Int, height: Int): Drawa
|
|||
return BitmapDrawable(resources, bmpScaled)
|
||||
}
|
||||
|
||||
fun Drawable.toBitmap(scaleFactor: Float, config: Bitmap.Config? = null): Bitmap {
|
||||
return toBitmap((intrinsicHeight*scaleFactor).toInt(), (intrinsicWidth*scaleFactor).toInt(), config)
|
||||
}
|
||||
|
||||
fun Drawable.getBitmapDrawable(): Bitmap {
|
||||
val bmp = Bitmap.createBitmap(bounds.width(), bounds.height(), Bitmap.Config.ARGB_8888)
|
||||
val canvas = Canvas(bmp)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package code.name.monkey.retromusic.extensions
|
||||
|
||||
import java.io.BufferedOutputStream
|
||||
import java.util.zip.ZipOutputStream
|
||||
|
||||
fun BufferedOutputStream.zipOutputStream(): ZipOutputStream = ZipOutputStream(this)
|
|
@ -24,7 +24,6 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import androidx.appcompat.content.res.AppCompatResources
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import com.google.android.material.appbar.MaterialToolbar
|
||||
|
@ -58,12 +57,6 @@ inline fun <reified T : Any> Fragment.extraNotNull(key: String, default: T? = nu
|
|||
requireNotNull(if (value is T) value else default) { key }
|
||||
}
|
||||
|
||||
val NavHostFragment.currentFragment: Fragment?
|
||||
get() = targetFragment
|
||||
|
||||
val FragmentManager.currentNavigationFragment: Fragment?
|
||||
get() = primaryNavigationFragment?.childFragmentManager?.fragments?.first()
|
||||
|
||||
fun AppCompatActivity.currentFragment(navHostId: Int): Fragment? {
|
||||
val navHostFragment: NavHostFragment =
|
||||
supportFragmentManager.findFragmentById(navHostId) as NavHostFragment
|
||||
|
@ -80,12 +73,12 @@ fun <T> Fragment.whichFragment(@IdRes id: Int): T {
|
|||
return childFragmentManager.findFragmentById(id) as T
|
||||
}
|
||||
|
||||
fun Fragment.showToast(@StringRes stringRes: Int) {
|
||||
showToast(getString(stringRes))
|
||||
fun Fragment.showToast(@StringRes stringRes: Int, duration: Int = Toast.LENGTH_SHORT) {
|
||||
showToast(getString(stringRes), duration)
|
||||
}
|
||||
|
||||
fun Fragment.showToast(message: String) {
|
||||
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
|
||||
fun Fragment.showToast(message: String, duration: Int = Toast.LENGTH_SHORT) {
|
||||
Toast.makeText(requireContext(), message, duration).show()
|
||||
}
|
||||
|
||||
fun Context.getDrawableCompat(@DrawableRes drawableRes: Int): Drawable {
|
||||
|
|
|
@ -8,6 +8,6 @@ fun WindowInsetsCompat?.safeGetBottomInsets(): Int {
|
|||
return if (PreferenceUtil.isFullScreenMode) {
|
||||
return 0
|
||||
} else {
|
||||
this?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom ?: RetroUtil.getNavigationBarHeight()
|
||||
this?.getInsets(WindowInsetsCompat.Type.systemBars())?.bottom ?: RetroUtil.navigationBarHeight
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
package code.name.monkey.retromusic.extensions
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.net.toUri
|
||||
import androidx.fragment.app.Fragment
|
||||
import java.io.OutputStream
|
||||
|
||||
|
@ -30,3 +32,15 @@ fun Fragment.createNewFile(
|
|||
}
|
||||
startForResult.launch(intent)
|
||||
}
|
||||
|
||||
fun Context.openUrl(url: String) {
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.data = url.toUri()
|
||||
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
startActivity(i)
|
||||
}
|
||||
|
||||
|
||||
fun Fragment.openUrl(url: String) {
|
||||
requireContext().openUrl(url)
|
||||
}
|
|
@ -16,10 +16,13 @@ package code.name.monkey.retromusic.extensions
|
|||
|
||||
import android.animation.Animator
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.ViewTreeObserver
|
||||
import android.view.animation.AnimationUtils
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.EditText
|
||||
import androidx.annotation.LayoutRes
|
||||
|
@ -32,6 +35,7 @@ import code.name.monkey.appthemehelper.ThemeStore
|
|||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import dev.chrisbanes.insetter.applyInsetter
|
||||
|
||||
|
@ -58,6 +62,84 @@ fun EditText.appHandleColor(): EditText {
|
|||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Potentially animate showing a [BottomNavigationView].
|
||||
*
|
||||
* Abruptly changing the visibility leads to a re-layout of main content, animating
|
||||
* `translationY` leaves a gap where the view was that content does not fill.
|
||||
*
|
||||
* Instead, take a snapshot of the view, and animate this in, only changing the visibility (and
|
||||
* thus layout) when the animation completes.
|
||||
*/
|
||||
fun BottomNavigationView.show() {
|
||||
if (isVisible) return
|
||||
|
||||
val parent = parent as ViewGroup
|
||||
// View needs to be laid out to create a snapshot & know position to animate. If view isn't
|
||||
// laid out yet, need to do this manually.
|
||||
if (!isLaidOut) {
|
||||
measure(
|
||||
View.MeasureSpec.makeMeasureSpec(parent.width, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(parent.height, View.MeasureSpec.AT_MOST)
|
||||
)
|
||||
layout(parent.left, parent.height - measuredHeight, parent.right, parent.height)
|
||||
}
|
||||
|
||||
val drawable = BitmapDrawable(context.resources, drawToBitmap())
|
||||
drawable.setBounds(left, parent.height, right, parent.height + height)
|
||||
parent.overlay.add(drawable)
|
||||
ValueAnimator.ofInt(parent.height, top).apply {
|
||||
duration = 300
|
||||
interpolator = AnimationUtils.loadInterpolator(
|
||||
context,
|
||||
android.R.interpolator.linear_out_slow_in
|
||||
)
|
||||
addUpdateListener {
|
||||
val newTop = it.animatedValue as Int
|
||||
drawable.setBounds(left, newTop, right, newTop + height)
|
||||
}
|
||||
doOnEnd {
|
||||
parent.overlay.remove(drawable)
|
||||
isVisible = true
|
||||
}
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Potentially animate hiding a [BottomNavigationView].
|
||||
*
|
||||
* Abruptly changing the visibility leads to a re-layout of main content, animating
|
||||
* `translationY` leaves a gap where the view was that content does not fill.
|
||||
*
|
||||
* Instead, take a snapshot, instantly hide the view (so content lays out to fill), then animate
|
||||
* out the snapshot.
|
||||
*/
|
||||
fun BottomNavigationView.hide() {
|
||||
if (isGone) return
|
||||
|
||||
val drawable = BitmapDrawable(context.resources, drawToBitmap())
|
||||
val parent = parent as ViewGroup
|
||||
drawable.setBounds(left, top, right, bottom)
|
||||
parent.overlay.add(drawable)
|
||||
isGone = true
|
||||
ValueAnimator.ofInt(top, parent.height).apply {
|
||||
duration = 300L
|
||||
interpolator = AnimationUtils.loadInterpolator(
|
||||
context,
|
||||
android.R.interpolator.fast_out_linear_in
|
||||
)
|
||||
addUpdateListener {
|
||||
val newTop = it.animatedValue as Int
|
||||
drawable.setBounds(left, newTop, right, newTop + height)
|
||||
}
|
||||
doOnEnd {
|
||||
parent.overlay.remove(drawable)
|
||||
}
|
||||
start()
|
||||
}
|
||||
}
|
||||
|
||||
fun View.translateYAnimate(value: Float): Animator {
|
||||
return ObjectAnimator.ofFloat(this, "translationY", value)
|
||||
.apply {
|
||||
|
@ -122,7 +204,7 @@ fun View.focusAndShowKeyboard() {
|
|||
*/
|
||||
fun View.drawAboveSystemBars(onlyPortrait: Boolean = true) {
|
||||
if (PreferenceUtil.isFullScreenMode) return
|
||||
if (onlyPortrait && RetroUtil.isLandscape()) return
|
||||
if (onlyPortrait && RetroUtil.isLandscape) return
|
||||
applyInsetter {
|
||||
type(navigationBars = true) {
|
||||
margin()
|
||||
|
|
|
@ -15,11 +15,13 @@
|
|||
package code.name.monkey.retromusic.fragments
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import androidx.core.animation.doOnEnd
|
||||
import androidx.lifecycle.*
|
||||
import code.name.monkey.retromusic.*
|
||||
import code.name.monkey.retromusic.db.*
|
||||
import code.name.monkey.retromusic.extensions.showToast
|
||||
import code.name.monkey.retromusic.fragments.ReloadType.*
|
||||
import code.name.monkey.retromusic.fragments.search.Filter
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
|
@ -45,7 +47,6 @@ class LibraryViewModel(
|
|||
private val songs = MutableLiveData<List<Song>>()
|
||||
private val artists = MutableLiveData<List<Artist>>()
|
||||
private val playlists = MutableLiveData<List<PlaylistWithSongs>>()
|
||||
private val legacyPlaylists = MutableLiveData<List<Playlist>>()
|
||||
private val genres = MutableLiveData<List<Genre>>()
|
||||
private val searchResults = MutableLiveData<List<Any>>()
|
||||
private val fabMargin = MutableLiveData(0)
|
||||
|
@ -69,41 +70,21 @@ class LibraryViewModel(
|
|||
|
||||
fun getSearchResult(): LiveData<List<Any>> = searchResults
|
||||
|
||||
fun getSongs(): LiveData<List<Song>> {
|
||||
return songs
|
||||
}
|
||||
fun getSongs(): LiveData<List<Song>> = songs
|
||||
|
||||
fun getAlbums(): LiveData<List<Album>> {
|
||||
return albums
|
||||
}
|
||||
fun getAlbums(): LiveData<List<Album>> = albums
|
||||
|
||||
fun getArtists(): LiveData<List<Artist>> {
|
||||
return artists
|
||||
}
|
||||
fun getArtists(): LiveData<List<Artist>> = artists
|
||||
|
||||
fun getPlaylists(): LiveData<List<PlaylistWithSongs>> {
|
||||
return playlists
|
||||
}
|
||||
fun getPlaylists(): LiveData<List<PlaylistWithSongs>> = playlists
|
||||
|
||||
fun getLegacyPlaylist(): LiveData<List<Playlist>> {
|
||||
return legacyPlaylists
|
||||
}
|
||||
fun getGenre(): LiveData<List<Genre>> = genres
|
||||
|
||||
fun getGenre(): LiveData<List<Genre>> {
|
||||
return genres
|
||||
}
|
||||
fun getHome(): LiveData<List<Home>> = home
|
||||
|
||||
fun getHome(): LiveData<List<Home>> {
|
||||
return home
|
||||
}
|
||||
fun getSuggestions(): LiveData<List<Song>> = suggestions
|
||||
|
||||
fun getSuggestions(): LiveData<List<Song>> {
|
||||
return suggestions
|
||||
}
|
||||
|
||||
fun getFabMargin(): LiveData<Int> {
|
||||
return fabMargin
|
||||
}
|
||||
fun getFabMargin(): LiveData<Int> = fabMargin
|
||||
|
||||
private suspend fun fetchSongs() {
|
||||
songs.postValue(repository.allSongs())
|
||||
|
@ -111,7 +92,6 @@ class LibraryViewModel(
|
|||
|
||||
private suspend fun fetchAlbums() {
|
||||
albums.postValue(repository.fetchAlbums())
|
||||
|
||||
}
|
||||
|
||||
private suspend fun fetchArtists() {
|
||||
|
@ -126,12 +106,6 @@ class LibraryViewModel(
|
|||
playlists.postValue(repository.fetchPlaylistWithSongs())
|
||||
}
|
||||
|
||||
private fun fetchLegacyPlaylist() {
|
||||
viewModelScope.launch(IO) {
|
||||
legacyPlaylists.postValue(repository.fetchLegacyPlaylist())
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun fetchGenres() {
|
||||
genres.postValue(repository.fetchGenres())
|
||||
}
|
||||
|
@ -146,7 +120,7 @@ class LibraryViewModel(
|
|||
|
||||
fun search(query: String?, filter: Filter) =
|
||||
viewModelScope.launch(IO) {
|
||||
val result =repository.search(query, filter)
|
||||
val result = repository.search(query, filter)
|
||||
searchResults.postValue(result)
|
||||
}
|
||||
|
||||
|
@ -267,35 +241,22 @@ class LibraryViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun deleteTracks(songs: List<Song>) = viewModelScope.launch(IO) {
|
||||
repository.deleteSongs(songs)
|
||||
fetchPlaylists()
|
||||
loadLibraryContent()
|
||||
}
|
||||
|
||||
fun recentSongs(): LiveData<List<Song>> = liveData {
|
||||
fun recentSongs(): LiveData<List<Song>> = liveData(IO) {
|
||||
emit(repository.recentSongs())
|
||||
}
|
||||
|
||||
fun playCountSongs(): LiveData<List<Song>> = liveData {
|
||||
val songs = repository.playCountSongs().map {
|
||||
it.toSong()
|
||||
}
|
||||
emit(songs)
|
||||
// Cleaning up deleted or moved songs
|
||||
withContext(IO) {
|
||||
songs.forEach { song ->
|
||||
fun playCountSongs(): LiveData<List<Song>> = liveData(IO) {
|
||||
repository.playCountSongs().forEach { song ->
|
||||
if (!File(song.data).exists() || song.id == -1L) {
|
||||
repository.deleteSongInPlayCount(song.toPlayCount())
|
||||
repository.deleteSongInPlayCount(song)
|
||||
}
|
||||
}
|
||||
emit(repository.playCountSongs().map {
|
||||
it.toSong()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun artists(type: Int): LiveData<List<Artist>> = liveData {
|
||||
fun artists(type: Int): LiveData<List<Artist>> = liveData(IO) {
|
||||
when (type) {
|
||||
TOP_ARTISTS -> emit(repository.topArtists())
|
||||
RECENT_ARTISTS -> {
|
||||
|
@ -304,7 +265,7 @@ class LibraryViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun albums(type: Int): LiveData<List<Album>> = liveData {
|
||||
fun albums(type: Int): LiveData<List<Album>> = liveData(IO) {
|
||||
when (type) {
|
||||
TOP_ALBUMS -> emit(repository.topAlbums())
|
||||
RECENT_ALBUMS -> {
|
||||
|
@ -313,29 +274,25 @@ class LibraryViewModel(
|
|||
}
|
||||
}
|
||||
|
||||
fun artist(artistId: Long): LiveData<Artist> = liveData {
|
||||
fun artist(artistId: Long): LiveData<Artist> = liveData(IO) {
|
||||
emit(repository.artistById(artistId))
|
||||
}
|
||||
|
||||
fun fetchContributors(): LiveData<List<Contributor>> = liveData {
|
||||
fun fetchContributors(): LiveData<List<Contributor>> = liveData(IO) {
|
||||
emit(repository.contributor())
|
||||
}
|
||||
|
||||
fun observableHistorySongs(): LiveData<List<Song>> {
|
||||
val songs = repository.historySong().map {
|
||||
it.toSong()
|
||||
}
|
||||
songHistory.value = songs
|
||||
// Cleaning up deleted or moved songs
|
||||
viewModelScope.launch {
|
||||
songs.forEach { song ->
|
||||
viewModelScope.launch(IO) {
|
||||
repository.historySong().forEach { song ->
|
||||
if (!File(song.data).exists() || song.id == -1L) {
|
||||
repository.deleteSongInHistory(song.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
songHistory.value = repository.historySong().map {
|
||||
|
||||
songHistory.postValue(repository.historySong().map {
|
||||
it.toSong()
|
||||
})
|
||||
}
|
||||
return songHistory
|
||||
}
|
||||
|
@ -366,12 +323,10 @@ class LibraryViewModel(
|
|||
fun favorites() = repository.favorites()
|
||||
|
||||
fun clearSearchResult() {
|
||||
viewModelScope.launch {
|
||||
searchResults.postValue(emptyList())
|
||||
}
|
||||
searchResults.value = emptyList()
|
||||
}
|
||||
|
||||
fun addToPlaylist(playlistName: String, songs: List<Song>) {
|
||||
fun addToPlaylist(context: Context, playlistName: String, songs: List<Song>) {
|
||||
viewModelScope.launch(IO) {
|
||||
val playlists = checkPlaylistExists(playlistName)
|
||||
if (playlists.isEmpty()) {
|
||||
|
@ -379,12 +334,8 @@ class LibraryViewModel(
|
|||
createPlaylist(PlaylistEntity(playlistName = playlistName))
|
||||
insertSongs(songs.map { it.toSongEntity(playlistId) })
|
||||
withContext(Main) {
|
||||
Toast.makeText(
|
||||
App.getContext(),
|
||||
App.getContext()
|
||||
.getString(R.string.playlist_created_sucessfully, playlistName),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
context.showToast(context.getString(R.string.playlist_created_sucessfully,
|
||||
playlistName))
|
||||
}
|
||||
} else {
|
||||
val playlist = playlists.firstOrNull()
|
||||
|
@ -396,17 +347,18 @@ class LibraryViewModel(
|
|||
}
|
||||
forceReload(Playlists)
|
||||
withContext(Main) {
|
||||
Toast.makeText(App.getContext(), App.getContext().getString(
|
||||
context.showToast(
|
||||
context.getString(
|
||||
R.string.added_song_count_to_playlist,
|
||||
songs.size,
|
||||
playlistName
|
||||
), Toast.LENGTH_SHORT).show()
|
||||
playlistName),
|
||||
Toast.LENGTH_SHORT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setFabMargin(bottomMargin: Int) {
|
||||
val currentValue = DensityUtil.dip2px(App.getContext(), 16F) +
|
||||
fun setFabMargin(context: Context, bottomMargin: Int) {
|
||||
val currentValue = DensityUtil.dip2px(context, 16F) +
|
||||
bottomMargin
|
||||
ValueAnimator.ofInt(fabMargin.value!!, currentValue).apply {
|
||||
addUpdateListener {
|
||||
|
|
|
@ -14,13 +14,10 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.about
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.app.ShareCompat
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.updatePadding
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
|
@ -29,9 +26,10 @@ import code.name.monkey.retromusic.Constants
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.ContributorAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentAboutBinding
|
||||
import code.name.monkey.retromusic.extensions.openUrl
|
||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import dev.chrisbanes.insetter.applyInsetter
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
||||
class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
|
||||
|
@ -45,36 +43,31 @@ class AboutFragment : Fragment(R.layout.fragment_about), View.OnClickListener {
|
|||
binding.aboutContent.cardOther.version.setSummary(getAppVersion())
|
||||
setUpView()
|
||||
loadContributors()
|
||||
// This is a workaround as CollapsingToolbarLayout consumes insets and
|
||||
// insets are not passed to child views
|
||||
// https://github.com/material-components/material-components-android/issues/1310
|
||||
if (!RetroUtil.isLandscape()) {
|
||||
binding.aboutContent.root.updatePadding(bottom = RetroUtil.getNavigationBarHeight())
|
||||
}
|
||||
}
|
||||
|
||||
private fun openUrl(url: String) {
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
i.data = url.toUri()
|
||||
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
startActivity(i)
|
||||
binding.aboutContent.root.applyInsetter {
|
||||
type(navigationBars = true) {
|
||||
padding()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setUpView() {
|
||||
binding.aboutContent.cardRetroInfo.appGithub.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.faqLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.telegramLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.appRate.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.appTranslation.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.appShare.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.donateLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.bugReportLink.setOnClickListener(this)
|
||||
|
||||
binding.aboutContent.cardSocial.telegramLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.instagramLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.twitterLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.pinterestLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.websiteLink.setOnClickListener(this)
|
||||
|
||||
binding.aboutContent.cardOther.changelog.setOnClickListener(this)
|
||||
binding.aboutContent.cardOther.openSource.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.pinterestLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardRetroInfo.bugReportLink.setOnClickListener(this)
|
||||
binding.aboutContent.cardSocial.websiteLink.setOnClickListener(this)
|
||||
}
|
||||
|
||||
override fun onClick(view: View) {
|
||||
|
|
|
@ -112,23 +112,22 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentAlbumDetailsBinding.bind(view)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.addMusicServiceEventListener(detailsViewModel)
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
|
||||
binding.toolbar.title = " "
|
||||
binding.albumCoverContainer.setTransitionName(arguments.extraAlbumId.toString())
|
||||
binding.albumCoverContainer.transitionName = arguments.extraAlbumId.toString()
|
||||
postponeEnterTransition()
|
||||
detailsViewModel.getAlbum().observe(viewLifecycleOwner) {
|
||||
requireView().doOnPreDraw {
|
||||
view.doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
albumArtistExists = !it.albumArtist.isNullOrEmpty()
|
||||
showAlbum(it)
|
||||
if (albumArtistExists) {
|
||||
binding.artistImage.setTransitionName(album.albumArtist)
|
||||
binding.artistImage.transitionName = if (albumArtistExists) {
|
||||
album.albumArtist
|
||||
} else {
|
||||
binding.artistImage.setTransitionName(album.artistId.toString())
|
||||
album.artistId.toString()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -308,7 +307,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
.load(
|
||||
RetroGlideExtension.getArtistModel(
|
||||
artist,
|
||||
PreferenceUtil.isAllowedToDownloadMetadata()
|
||||
PreferenceUtil.isAllowedToDownloadMetadata(requireContext())
|
||||
)
|
||||
)
|
||||
.artistImageOptions(artist)
|
||||
|
@ -347,8 +346,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
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)
|
||||
|
@ -360,7 +358,7 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
|
|||
)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
return handleSortOrderMenuItem(item)
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class AlbumDetailsViewModel(
|
|||
emit(artist)
|
||||
}
|
||||
|
||||
fun getAlbumInfo(album: Album): LiveData<Result<LastFmAlbum>> = liveData {
|
||||
fun getAlbumInfo(album: Album): LiveData<Result<LastFmAlbum>> = liveData(IO) {
|
||||
emit(Result.Loading)
|
||||
emit(repository.albumInfo(album.artistName, album.title))
|
||||
}
|
||||
|
|
|
@ -158,10 +158,10 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
|||
reenterTransition = null
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateMenu(menu, inflater)
|
||||
val gridSizeItem: MenuItem = menu.findItem(R.id.action_grid_size)
|
||||
if (RetroUtil.isLandscape()) {
|
||||
if (RetroUtil.isLandscape) {
|
||||
gridSizeItem.setTitle(R.string.action_grid_size_land)
|
||||
}
|
||||
setUpGridSizeMenu(gridSizeItem.subMenu)
|
||||
|
@ -267,7 +267,7 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
|||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
if (handleGridSizeMenuItem(item)) {
|
||||
return true
|
||||
}
|
||||
|
@ -277,7 +277,7 @@ class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment<AlbumAdapter, GridL
|
|||
if (handleSortOrderMenuItem(item)) {
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
return super.onMenuItemSelected(item)
|
||||
}
|
||||
|
||||
private fun handleSortOrderMenuItem(
|
||||
|
|
|
@ -10,6 +10,7 @@ import android.view.MenuInflater
|
|||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.activity.addCallback
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.text.parseAsHtml
|
||||
|
@ -84,14 +85,13 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentArtistDetailsBinding.bind(view)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.addMusicServiceEventListener(detailsViewModel)
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
binding.toolbar.title = null
|
||||
binding.artistCoverContainer.setTransitionName((artistId ?: artistName).toString())
|
||||
binding.artistCoverContainer.transitionName = (artistId ?: artistName).toString()
|
||||
postponeEnterTransition()
|
||||
detailsViewModel.getArtist().observe(viewLifecycleOwner) {
|
||||
requireView().doOnPreDraw {
|
||||
view.doOnPreDraw {
|
||||
startPostponedEnterTransition()
|
||||
}
|
||||
showArtist(it)
|
||||
|
@ -146,7 +146,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
}
|
||||
this.artist = artist
|
||||
loadArtistImage(artist)
|
||||
if (RetroUtil.isAllowedToDownloadMetadata(requireContext())) {
|
||||
if (PreferenceUtil.isAllowedToDownloadMetadata(requireContext())) {
|
||||
loadBiography(artist.name)
|
||||
}
|
||||
binding.artistTitle.text = artist.name
|
||||
|
@ -173,7 +173,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
|
||||
private fun loadBiography(
|
||||
name: String,
|
||||
lang: String? = Locale.getDefault().language
|
||||
lang: String? = Locale.getDefault().language,
|
||||
) {
|
||||
biography = null
|
||||
this.lang = lang
|
||||
|
@ -245,7 +245,7 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
return handleSortOrderMenuItem(item)
|
||||
}
|
||||
|
||||
|
@ -274,15 +274,16 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
R.id.action_set_artist_image -> {
|
||||
val intent = Intent(Intent.ACTION_GET_CONTENT)
|
||||
intent.type = "image/*"
|
||||
startActivityForResult(
|
||||
Intent.createChooser(intent, getString(R.string.pick_from_local_storage)),
|
||||
REQUEST_CODE_SELECT_IMAGE
|
||||
)
|
||||
selectImageLauncher.launch(Intent.createChooser(intent,
|
||||
getString(R.string.pick_from_local_storage)))
|
||||
return true
|
||||
}
|
||||
R.id.action_reset_artist_image -> {
|
||||
showToast(resources.getString(R.string.updating))
|
||||
CustomArtistImageUtil.getInstance(requireContext()).resetCustomArtistImage(artist)
|
||||
lifecycleScope.launch {
|
||||
CustomArtistImageUtil.getInstance(requireContext())
|
||||
.resetCustomArtistImage(artist)
|
||||
}
|
||||
forceDownload = true
|
||||
return true
|
||||
}
|
||||
|
@ -295,18 +296,18 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
PopupMenu(requireContext(), binding.fragmentArtistContent.songSortOrder).apply {
|
||||
inflate(R.menu.menu_artist_song_sort_order)
|
||||
setUpSortOrderMenu(menu)
|
||||
setOnMenuItemClickListener { menuItem ->
|
||||
val sortOrder = when (menuItem.itemId) {
|
||||
setOnMenuItemClickListener { item ->
|
||||
val sortOrder = when (item.itemId) {
|
||||
R.id.action_sort_order_title -> SortOrder.ArtistSongSortOrder.SONG_A_Z
|
||||
R.id.action_sort_order_title_desc -> SortOrder.ArtistSongSortOrder.SONG_Z_A
|
||||
R.id.action_sort_order_album -> SortOrder.ArtistSongSortOrder.SONG_ALBUM
|
||||
R.id.action_sort_order_year -> SortOrder.ArtistSongSortOrder.SONG_YEAR
|
||||
R.id.action_sort_order_song_duration -> SortOrder.ArtistSongSortOrder.SONG_DURATION
|
||||
else -> {
|
||||
throw IllegalArgumentException("invalid ${menuItem.title}")
|
||||
throw IllegalArgumentException("invalid ${item.title}")
|
||||
}
|
||||
}
|
||||
menuItem.isChecked = true
|
||||
item.isChecked = true
|
||||
setSaveSortOrder(sortOrder)
|
||||
return@setOnMenuItemClickListener true
|
||||
}
|
||||
|
@ -322,38 +323,36 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
|
||||
private fun setUpSortOrderMenu(sortOrder: Menu) {
|
||||
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_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-> {
|
||||
else -> {
|
||||
throw IllegalArgumentException("invalid $savedSongSortOrder")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
when (requestCode) {
|
||||
REQUEST_CODE_SELECT_IMAGE -> if (resultCode == Activity.RESULT_OK) {
|
||||
data?.data?.let {
|
||||
private val selectImageLauncher =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
|
||||
if (result.resultCode == Activity.RESULT_OK) {
|
||||
result.data?.data?.let {
|
||||
lifecycleScope.launch {
|
||||
CustomArtistImageUtil.getInstance(requireContext())
|
||||
.setCustomArtistImage(artist, it)
|
||||
}
|
||||
}
|
||||
else -> if (resultCode == Activity.RESULT_OK) {
|
||||
println("OK")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_artist_detail, menu)
|
||||
}
|
||||
|
||||
|
@ -395,8 +394,4 @@ abstract class AbsArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragm
|
|||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val REQUEST_CODE_SELECT_IMAGE = 9002
|
||||
}
|
||||
}
|
|
@ -168,10 +168,10 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
|||
reenterTransition = null
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateMenu(menu, inflater)
|
||||
val gridSizeItem: MenuItem = menu.findItem(R.id.action_grid_size)
|
||||
if (RetroUtil.isLandscape()) {
|
||||
if (RetroUtil.isLandscape) {
|
||||
gridSizeItem.setTitle(R.string.action_grid_size_land)
|
||||
}
|
||||
setUpGridSizeMenu(gridSizeItem.subMenu)
|
||||
|
@ -261,7 +261,7 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
|||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
if (handleGridSizeMenuItem(item)) {
|
||||
return true
|
||||
}
|
||||
|
@ -274,7 +274,7 @@ class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment<ArtistAdapter, Gri
|
|||
if (handleAlbumArtistMenu(item)) {
|
||||
return true
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
return super.onMenuItemSelected(item)
|
||||
}
|
||||
|
||||
private fun handleAlbumArtistMenu(item: MenuItem): Boolean {
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.content.Intent
|
|||
import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.isVisible
|
||||
|
@ -20,6 +19,7 @@ import code.name.monkey.retromusic.databinding.FragmentBackupBinding
|
|||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.accentOutlineColor
|
||||
import code.name.monkey.retromusic.extensions.materialDialog
|
||||
import code.name.monkey.retromusic.extensions.showToast
|
||||
import code.name.monkey.retromusic.helper.BackupHelper
|
||||
import code.name.monkey.retromusic.helper.sanitize
|
||||
import code.name.monkey.retromusic.util.BackupUtil
|
||||
|
@ -47,7 +47,7 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC
|
|||
else
|
||||
backupAdapter?.swapDataset(listOf())
|
||||
}
|
||||
backupViewModel.loadBackups(requireContext())
|
||||
backupViewModel.loadBackups()
|
||||
val openFilePicker = registerForActivityResult(ActivityResultContracts.OpenDocument()) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
it?.let {
|
||||
|
@ -98,7 +98,7 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC
|
|||
// Text submitted with the action button
|
||||
lifecycleScope.launch {
|
||||
BackupHelper.createBackup(requireContext(), text.sanitize())
|
||||
backupViewModel.loadBackups(requireContext())
|
||||
backupViewModel.loadBackups()
|
||||
}
|
||||
}
|
||||
positiveButton(android.R.string.ok)
|
||||
|
@ -122,13 +122,9 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC
|
|||
try {
|
||||
file.delete()
|
||||
} catch (exception: SecurityException) {
|
||||
Toast.makeText(
|
||||
activity,
|
||||
"Could not delete backup",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
showToast("Could not delete backup")
|
||||
}
|
||||
backupViewModel.loadBackups(requireContext())
|
||||
backupViewModel.loadBackups()
|
||||
return true
|
||||
}
|
||||
R.id.action_share -> {
|
||||
|
@ -149,13 +145,9 @@ class BackupFragment : Fragment(R.layout.fragment_backup), BackupAdapter.BackupC
|
|||
File(file.parent, "$text${BackupHelper.APPEND_EXTENSION}")
|
||||
if (!renamedFile.exists()) {
|
||||
file.renameTo(renamedFile)
|
||||
backupViewModel.loadBackups(requireContext())
|
||||
backupViewModel.loadBackups()
|
||||
} else {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
"File already exists",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
showToast("File already exists")
|
||||
}
|
||||
}
|
||||
positiveButton(android.R.string.ok)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package code.name.monkey.retromusic.fragments.backup
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
|
@ -20,7 +19,7 @@ class BackupViewModel : ViewModel() {
|
|||
private val backupsMutableLiveData = MutableLiveData<List<File>>()
|
||||
val backupsLiveData: LiveData<List<File>> = backupsMutableLiveData
|
||||
|
||||
fun loadBackups(context: Context) {
|
||||
fun loadBackups() {
|
||||
BackupHelper.getBackupRoot().listFiles { _, name ->
|
||||
return@listFiles name.endsWith(BackupHelper.BACKUP_EXTENSION)
|
||||
}?.toList()?.let {
|
||||
|
|
|
@ -10,12 +10,17 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.ActivityRestoreBinding
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.accentOutlineColor
|
||||
import code.name.monkey.retromusic.extensions.addAccentColor
|
||||
import code.name.monkey.retromusic.helper.BackupContent
|
||||
import code.name.monkey.retromusic.helper.BackupContent.*
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.theme.ThemeManager
|
||||
import code.name.monkey.retromusic.util.theme.getNightMode
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import com.google.android.material.color.DynamicColorsOptions
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
@ -33,14 +38,20 @@ class RestoreActivity : AppCompatActivity() {
|
|||
setWidth()
|
||||
val backupUri = intent?.data
|
||||
binding.backupName.setText(getFileName(backupUri))
|
||||
binding.cancelButton.accentOutlineColor()
|
||||
binding.cancelButton.setOnClickListener {
|
||||
finish()
|
||||
}
|
||||
binding.restoreButton.accentColor()
|
||||
binding.checkArtistImages.addAccentColor()
|
||||
binding.checkPlaylists.addAccentColor()
|
||||
binding.checkSettings.addAccentColor()
|
||||
binding.checkUserImages.addAccentColor()
|
||||
binding.restoreButton.setOnClickListener {
|
||||
val backupContents = mutableListOf<BackupContent>()
|
||||
if (binding.checkSettings.isChecked) backupContents.add(SETTINGS)
|
||||
if (binding.checkDatabases.isChecked) backupContents.add(PLAYLISTS)
|
||||
if (binding.checkPlaylists.isChecked) backupContents.add(PLAYLISTS)
|
||||
if (binding.checkArtistImages.isChecked) backupContents.add(CUSTOM_ARTIST_IMAGES)
|
||||
if (binding.checkSettings.isChecked) backupContents.add(SETTINGS)
|
||||
if (binding.checkUserImages.isChecked) backupContents.add(USER_IMAGES)
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
if (backupUri != null) {
|
||||
|
@ -53,13 +64,15 @@ class RestoreActivity : AppCompatActivity() {
|
|||
}
|
||||
|
||||
private fun updateTheme() {
|
||||
AppCompatDelegate.setDefaultNightMode(ThemeManager.getNightMode())
|
||||
AppCompatDelegate.setDefaultNightMode(getNightMode())
|
||||
|
||||
// Apply dynamic colors to activity if enabled
|
||||
if (PreferenceUtil.materialYou) {
|
||||
DynamicColors.applyIfAvailable(
|
||||
DynamicColors.applyToActivityIfAvailable(
|
||||
this,
|
||||
com.google.android.material.R.style.ThemeOverlay_Material3_DynamicColors_DayNight
|
||||
DynamicColorsOptions.Builder()
|
||||
.setThemeOverlay(R.style.ThemeOverlay_Material3_DynamicColors_DayNight)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,21 +15,25 @@
|
|||
package code.name.monkey.retromusic.fragments.base
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.core.view.MenuHost
|
||||
import androidx.core.view.MenuProvider
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import code.name.monkey.retromusic.activities.MainActivity
|
||||
import code.name.monkey.retromusic.extensions.setTaskDescriptionColorAuto
|
||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
|
||||
abstract class AbsMainActivityFragment(@LayoutRes layout: Int) : AbsMusicServiceFragment(layout) {
|
||||
abstract class AbsMainActivityFragment(@LayoutRes layout: Int) : AbsMusicServiceFragment(layout),
|
||||
MenuProvider {
|
||||
val libraryViewModel: LibraryViewModel by sharedViewModel()
|
||||
|
||||
val mainActivity: MainActivity
|
||||
get() = activity as MainActivity
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.setTaskDescriptionColorAuto()
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
val menuHost: MenuHost = requireActivity()
|
||||
menuHost.addMenuProvider(this, viewLifecycleOwner, Lifecycle.State.STARTED)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ import androidx.core.view.isVisible
|
|||
import androidx.fragment.app.commit
|
||||
import androidx.fragment.app.replace
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.extensions.whichFragment
|
||||
import code.name.monkey.retromusic.fragments.MusicSeekSkipTouchListener
|
||||
import code.name.monkey.retromusic.fragments.other.VolumeFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
|
@ -224,8 +225,7 @@ abstract class AbsPlayerControlsFragment(@LayoutRes layout: Int) : AbsMusicServi
|
|||
}
|
||||
childFragmentManager.executePendingTransactions()
|
||||
}
|
||||
volumeFragment =
|
||||
childFragmentManager.findFragmentById(R.id.volumeFragmentContainer) as? VolumeFragment
|
||||
volumeFragment = whichFragment(R.id.volumeFragmentContainer)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
|
|
@ -20,7 +20,6 @@ import android.content.ContentUris
|
|||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.drawable.AnimatedVectorDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.media.MediaMetadataRetriever
|
||||
import android.os.Bundle
|
||||
import android.provider.MediaStore
|
||||
|
@ -29,7 +28,6 @@ import android.view.MenuItem
|
|||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.LayoutRes
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.core.os.bundleOf
|
||||
|
@ -48,10 +46,8 @@ import code.name.monkey.retromusic.activities.tageditor.SongTagEditorActivity
|
|||
import code.name.monkey.retromusic.db.PlaylistEntity
|
||||
import code.name.monkey.retromusic.db.toSongEntity
|
||||
import code.name.monkey.retromusic.dialogs.*
|
||||
import code.name.monkey.retromusic.extensions.currentFragment
|
||||
import code.name.monkey.retromusic.extensions.hide
|
||||
import code.name.monkey.retromusic.extensions.keepScreenOn
|
||||
import code.name.monkey.retromusic.extensions.whichFragment
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.LibraryViewModel
|
||||
import code.name.monkey.retromusic.fragments.NowPlayingScreen
|
||||
import code.name.monkey.retromusic.fragments.ReloadType
|
||||
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
|
||||
|
@ -60,22 +56,30 @@ import code.name.monkey.retromusic.interfaces.IPaletteColorHolder
|
|||
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.*
|
||||
import code.name.monkey.retromusic.util.NavigationUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.RingtoneManager
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
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 kotlin.math.abs
|
||||
|
||||
abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragment(layout),
|
||||
abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMusicServiceFragment(layout),
|
||||
Toolbar.OnMenuItemClickListener, IPaletteColorHolder, PlayerAlbumCoverFragment.Callbacks {
|
||||
|
||||
val libraryViewModel: LibraryViewModel by sharedViewModel()
|
||||
|
||||
val mainActivity: MainActivity
|
||||
get() = activity as MainActivity
|
||||
|
||||
private var playerAlbumCoverFragment: PlayerAlbumCoverFragment? = null
|
||||
|
||||
override fun onMenuItemClick(
|
||||
item: MenuItem
|
||||
item: MenuItem,
|
||||
): Boolean {
|
||||
val song = MusicPlayerRemote.currentSong
|
||||
when (item.itemId) {
|
||||
|
@ -196,7 +200,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
if (genre == null) {
|
||||
genre = "Not Specified"
|
||||
}
|
||||
Toast.makeText(context, genre, Toast.LENGTH_SHORT).show()
|
||||
showToast(genre)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -206,8 +210,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
private fun showLyricsIcon(item: MenuItem) {
|
||||
val icon =
|
||||
if (PreferenceUtil.showLyrics) R.drawable.ic_lyrics else R.drawable.ic_lyrics_outline
|
||||
val drawable: Drawable = RetroUtil.getTintedVectorDrawable(
|
||||
requireContext(),
|
||||
val drawable = requireContext().getTintedDrawable(
|
||||
icon,
|
||||
toolbarIconColor()
|
||||
)
|
||||
|
@ -240,7 +243,6 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
protected open fun toggleFavorite(song: Song) {
|
||||
lifecycleScope.launch(IO) {
|
||||
val playlist: PlaylistEntity = libraryViewModel.favoritePlaylist()
|
||||
if (playlist != null) {
|
||||
val songEntity = song.toSongEntity(playlist.playListId)
|
||||
val isFavorite = libraryViewModel.isSongFavorite(song.id)
|
||||
if (isFavorite) {
|
||||
|
@ -248,7 +250,6 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
} else {
|
||||
libraryViewModel.insertSongs(listOf(song.toSongEntity(playlist.playListId)))
|
||||
}
|
||||
}
|
||||
libraryViewModel.forceReload(ReloadType.Playlists)
|
||||
requireContext().sendBroadcast(Intent(MusicService.FAVORITE_STATE_CHANGED))
|
||||
}
|
||||
|
@ -264,8 +265,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
} else {
|
||||
if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
|
||||
}
|
||||
val drawable: Drawable = RetroUtil.getTintedVectorDrawable(
|
||||
requireContext(),
|
||||
val drawable = requireContext().getTintedDrawable(
|
||||
icon,
|
||||
toolbarIconColor()
|
||||
)
|
||||
|
@ -333,7 +333,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
e1: MotionEvent?,
|
||||
e2: MotionEvent?,
|
||||
distanceX: Float,
|
||||
distanceY: Float
|
||||
distanceY: Float,
|
||||
): Boolean {
|
||||
return when {
|
||||
abs(distanceX) > abs(distanceY) -> {
|
||||
|
@ -359,15 +359,6 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
|
|||
val TAG: String = AbsPlayerFragment::class.java.simpleName
|
||||
const val VISIBILITY_ANIM_DURATION: Long = 300
|
||||
}
|
||||
|
||||
protected fun getUpNextAndQueueTime(): String {
|
||||
val duration = MusicPlayerRemote.getQueueDurationMillis(MusicPlayerRemote.position)
|
||||
|
||||
return MusicUtil.buildInfoString(
|
||||
resources.getString(R.string.up_next),
|
||||
MusicUtil.getReadableDurationString(duration)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun goToArtist(activity: Activity) {
|
||||
|
|
|
@ -28,7 +28,7 @@ abstract class AbsRecyclerViewCustomGridSizeFragment<A : RecyclerView.Adapter<*>
|
|||
private var sortOrder: String? = null
|
||||
private var currentLayoutRes: Int = 0
|
||||
private val isLandscape: Boolean
|
||||
get() = RetroUtil.isLandscape()
|
||||
get() = RetroUtil.isLandscape
|
||||
|
||||
val maxGridSize: Int
|
||||
get() = if (isLandscape) {
|
||||
|
|
|
@ -199,13 +199,11 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
|||
binding.appBarLayout.setExpanded(true, true)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
override fun onPrepareMenu(menu: Menu) {
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), toolbar)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_main, menu)
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||
requireContext(),
|
||||
|
@ -215,7 +213,7 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
|||
)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.action_settings -> findNavController().navigate(
|
||||
R.id.settingsActivity,
|
||||
|
@ -231,7 +229,7 @@ abstract class AbsRecyclerViewFragment<A : RecyclerView.Adapter<*>, LM : Recycle
|
|||
"ShowCreatePlaylistDialog"
|
||||
)
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
|
|
@ -13,21 +13,20 @@
|
|||
*/
|
||||
package code.name.monkey.retromusic.fragments.folder
|
||||
|
||||
import android.app.Dialog
|
||||
import android.content.Context
|
||||
import android.media.MediaScannerConnection
|
||||
import android.os.Bundle
|
||||
import android.os.Environment
|
||||
import android.text.Html
|
||||
import android.view.Menu
|
||||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.webkit.MimeTypeMap
|
||||
import android.widget.Toast
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.loader.app.LoaderManager
|
||||
import androidx.loader.content.Loader
|
||||
import androidx.navigation.fragment.findNavController
|
||||
|
@ -36,7 +35,6 @@ import androidx.recyclerview.widget.RecyclerView
|
|||
import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor
|
||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.App
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.adapter.SongFileAdapter
|
||||
import code.name.monkey.retromusic.adapter.Storage
|
||||
|
@ -45,17 +43,13 @@ import code.name.monkey.retromusic.adapter.StorageClickListener
|
|||
import code.name.monkey.retromusic.databinding.FragmentFolderBinding
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.fragments.folder.FoldersFragment.ListPathsAsyncTask.OnPathsListedCallback
|
||||
import code.name.monkey.retromusic.fragments.folder.FoldersFragment.ListSongsAsyncTask.OnSongsListedCallback
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote.openQueue
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote.playingQueue
|
||||
import code.name.monkey.retromusic.helper.menu.SongMenuHelper.handleMenuClick
|
||||
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
|
||||
import code.name.monkey.retromusic.interfaces.ICabCallback
|
||||
import code.name.monkey.retromusic.interfaces.ICabHolder
|
||||
import code.name.monkey.retromusic.interfaces.ICallbacks
|
||||
import code.name.monkey.retromusic.interfaces.IMainActivityFragmentCallbacks
|
||||
import code.name.monkey.retromusic.misc.DialogAsyncTask
|
||||
import code.name.monkey.retromusic.misc.UpdateToastMediaScannerCompletionListener
|
||||
import code.name.monkey.retromusic.misc.WrappedAsyncTaskLoader
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
|
@ -64,16 +58,20 @@ import code.name.monkey.retromusic.util.FileUtil
|
|||
import code.name.monkey.retromusic.util.PreferenceUtil.startDirectory
|
||||
import code.name.monkey.retromusic.util.RetroColorUtil
|
||||
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.Crumb
|
||||
import code.name.monkey.retromusic.views.BreadCrumbLayout.SelectionCallback
|
||||
import com.afollestad.materialcab.attached.AttachedCab
|
||||
import com.afollestad.materialcab.attached.destroy
|
||||
import com.afollestad.materialcab.attached.isActive
|
||||
import com.afollestad.materialcab.createCab
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.File
|
||||
import java.io.FileFilter
|
||||
import java.io.IOException
|
||||
|
@ -101,7 +99,6 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
_binding = FragmentFolderBinding.bind(view)
|
||||
|
||||
mainActivity.addMusicServiceEventListener(libraryViewModel)
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
mainActivity.supportActionBar?.title = null
|
||||
|
@ -136,7 +133,6 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
if (savedInstanceState == null) {
|
||||
switchToFileAdapter()
|
||||
setCrumb(
|
||||
|
@ -186,48 +182,37 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
popupMenu.setOnMenuItemClickListener { item: MenuItem ->
|
||||
when (val itemId = item.itemId) {
|
||||
R.id.action_play_next, R.id.action_add_to_current_playing, R.id.action_add_to_playlist, R.id.action_delete_from_device -> {
|
||||
ListSongsAsyncTask(
|
||||
activity,
|
||||
null,
|
||||
object : OnSongsListedCallback {
|
||||
override fun onSongsListed(songs: List<Song>, extra: Any?) {
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
listSongs(
|
||||
requireContext(),
|
||||
toList(file),
|
||||
AUDIO_FILE_FILTER,
|
||||
fileComparator
|
||||
) { songs ->
|
||||
if (songs.isNotEmpty()) {
|
||||
SongsMenuHelper.handleMenuClick(
|
||||
requireActivity(), songs, itemId
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
.execute(
|
||||
ListSongsAsyncTask.LoadingInfo(
|
||||
toList(file), AUDIO_FILE_FILTER, fileComparator
|
||||
)
|
||||
)
|
||||
}
|
||||
return@setOnMenuItemClickListener true
|
||||
}
|
||||
R.id.action_add_to_blacklist -> {
|
||||
BlacklistStore.getInstance(App.getContext()).addPath(file)
|
||||
BlacklistStore.getInstance(requireContext()).addPath(file)
|
||||
return@setOnMenuItemClickListener true
|
||||
}
|
||||
R.id.action_set_as_start_directory -> {
|
||||
startDirectory = file
|
||||
Toast.makeText(
|
||||
activity,
|
||||
String.format(getString(R.string.new_start_directory), file.path),
|
||||
Toast.LENGTH_SHORT
|
||||
showToast(
|
||||
String.format(getString(R.string.new_start_directory), file.path)
|
||||
)
|
||||
.show()
|
||||
return@setOnMenuItemClickListener true
|
||||
}
|
||||
R.id.action_scan -> {
|
||||
ListPathsAsyncTask(
|
||||
activity,
|
||||
object : OnPathsListedCallback {
|
||||
override fun onPathsListed(paths: Array<String?>) {
|
||||
scanPaths(paths)
|
||||
lifecycleScope.launch {
|
||||
listPaths(file, AUDIO_FILE_FILTER) { paths -> scanPaths(paths) }
|
||||
}
|
||||
})
|
||||
.execute(ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER))
|
||||
return@setOnMenuItemClickListener true
|
||||
}
|
||||
}
|
||||
|
@ -238,32 +223,26 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
popupMenu.setOnMenuItemClickListener { item: MenuItem ->
|
||||
when (val itemId = item.itemId) {
|
||||
R.id.action_play_next, R.id.action_add_to_current_playing, R.id.action_add_to_playlist, R.id.action_go_to_album, R.id.action_go_to_artist, R.id.action_share, R.id.action_tag_editor, R.id.action_details, R.id.action_set_as_ringtone, R.id.action_delete_from_device -> {
|
||||
ListSongsAsyncTask(
|
||||
activity,
|
||||
null,
|
||||
object : OnSongsListedCallback {
|
||||
override fun onSongsListed(songs: List<Song>, extra: Any?) {
|
||||
handleMenuClick(
|
||||
requireActivity(), songs[0], itemId
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
listSongs(
|
||||
requireContext(),
|
||||
toList(file),
|
||||
AUDIO_FILE_FILTER,
|
||||
fileComparator
|
||||
) { songs ->
|
||||
if (songs.isNotEmpty()) {
|
||||
SongsMenuHelper.handleMenuClick(
|
||||
requireActivity(), songs, itemId
|
||||
)
|
||||
}
|
||||
})
|
||||
.execute(
|
||||
ListSongsAsyncTask.LoadingInfo(
|
||||
toList(file), AUDIO_FILE_FILTER, fileComparator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
return@setOnMenuItemClickListener true
|
||||
}
|
||||
R.id.action_scan -> {
|
||||
ListPathsAsyncTask(
|
||||
activity,
|
||||
object : OnPathsListedCallback {
|
||||
override fun onPathsListed(paths: Array<String?>) {
|
||||
scanPaths(paths)
|
||||
lifecycleScope.launch {
|
||||
listPaths(file, AUDIO_FILE_FILTER) { paths -> scanPaths(paths) }
|
||||
}
|
||||
})
|
||||
.execute(ListPathsAsyncTask.LoadingInfo(file, AUDIO_FILE_FILTER))
|
||||
return@setOnMenuItemClickListener true
|
||||
}
|
||||
}
|
||||
|
@ -282,16 +261,17 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
val fileFilter = FileFilter { pathname: File ->
|
||||
!pathname.isDirectory && AUDIO_FILE_FILTER.accept(pathname)
|
||||
}
|
||||
ListSongsAsyncTask(
|
||||
activity,
|
||||
mFile,
|
||||
object : OnSongsListedCallback {
|
||||
override fun onSongsListed(songs: List<Song>, extra: Any?) {
|
||||
val file1 = extra as File
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
listSongs(
|
||||
requireContext(),
|
||||
toList(mFile.parentFile),
|
||||
fileFilter,
|
||||
fileComparator
|
||||
) { songs ->
|
||||
if (songs.isNotEmpty()) {
|
||||
var startIndex = -1
|
||||
for (i in songs.indices) {
|
||||
if (file1
|
||||
.path
|
||||
if (mFile.path
|
||||
== songs[i].data
|
||||
) { // path is already canonical here
|
||||
startIndex = i
|
||||
|
@ -303,39 +283,29 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
} else {
|
||||
Snackbar.make(
|
||||
mainActivity.slidingPanel,
|
||||
Html.fromHtml(
|
||||
String.format(
|
||||
getString(R.string.not_listed_in_media_store), file1.name
|
||||
)
|
||||
),
|
||||
getString(R.string.not_listed_in_media_store), mFile.name
|
||||
|
||||
).parseAsHtml(),
|
||||
Snackbar.LENGTH_LONG
|
||||
)
|
||||
.setAction(
|
||||
R.string.action_scan
|
||||
) {
|
||||
ListPathsAsyncTask(
|
||||
requireActivity(),
|
||||
object : OnPathsListedCallback {
|
||||
override fun onPathsListed(paths: Array<String?>) {
|
||||
scanPaths(paths)
|
||||
lifecycleScope.launch {
|
||||
listPaths(mFile, AUDIO_FILE_FILTER) { paths ->
|
||||
scanPaths(
|
||||
paths
|
||||
)
|
||||
}
|
||||
}
|
||||
})
|
||||
.execute(
|
||||
ListPathsAsyncTask.LoadingInfo(
|
||||
file1, AUDIO_FILE_FILTER
|
||||
)
|
||||
)
|
||||
}
|
||||
.setActionTextColor(accentColor(requireActivity()))
|
||||
.show()
|
||||
}
|
||||
}
|
||||
})
|
||||
.execute(
|
||||
ListSongsAsyncTask.LoadingInfo(
|
||||
toList(mFile.parentFile), fileFilter, fileComparator
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -349,28 +319,23 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
|
||||
override fun onMultipleItemAction(item: MenuItem, files: ArrayList<File>) {
|
||||
val itemId = item.itemId
|
||||
ListSongsAsyncTask(
|
||||
activity,
|
||||
null,
|
||||
object : OnSongsListedCallback {
|
||||
override fun onSongsListed(songs: List<Song>, extra: Any?) {
|
||||
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
listSongs(requireContext(), files, AUDIO_FILE_FILTER, fileComparator) { songs ->
|
||||
if (songs.isNotEmpty()) {
|
||||
SongsMenuHelper.handleMenuClick(
|
||||
requireActivity(),
|
||||
songs,
|
||||
itemId
|
||||
requireActivity(), songs, itemId
|
||||
)
|
||||
}
|
||||
})
|
||||
.execute(ListSongsAsyncTask.LoadingInfo(files, AUDIO_FILE_FILTER, fileComparator))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
override fun onPrepareMenu(menu: Menu) {
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), binding.toolbar)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
menu.add(0, R.id.action_scan, 0, R.string.scan_media)
|
||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
|
||||
menu.add(0, R.id.action_go_to_start_directory, 1, R.string.action_go_to_start_directory)
|
||||
|
@ -387,7 +352,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.action_go_to_start_directory -> {
|
||||
setCrumb(
|
||||
|
@ -401,14 +366,9 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
R.id.action_scan -> {
|
||||
val crumb = activeCrumb
|
||||
if (crumb != null) {
|
||||
ListPathsAsyncTask(
|
||||
activity,
|
||||
object : OnPathsListedCallback {
|
||||
override fun onPathsListed(paths: Array<String?>) {
|
||||
scanPaths(paths)
|
||||
lifecycleScope.launch {
|
||||
listPaths(crumb.file, AUDIO_FILE_FILTER) { paths -> scanPaths(paths) }
|
||||
}
|
||||
})
|
||||
.execute(ListPathsAsyncTask.LoadingInfo(crumb.file, AUDIO_FILE_FILTER))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -421,7 +381,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
return true
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onQueueChanged() {
|
||||
|
@ -457,7 +417,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
if (_binding != null) {
|
||||
binding.recyclerView.updatePadding(
|
||||
bottom = if (count > 0 && playingQueue.isNotEmpty()) dip(R.dimen.mini_player_height_expanded)
|
||||
else dip(R.dimen.mini_player_height_expanded)
|
||||
else dip(R.dimen.mini_player_height)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -491,7 +451,7 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
return
|
||||
}
|
||||
if (toBeScanned.isEmpty()) {
|
||||
Toast.makeText(activity, R.string.nothing_to_scan, Toast.LENGTH_SHORT).show()
|
||||
showToast(R.string.nothing_to_scan)
|
||||
} else {
|
||||
MediaScannerConnection.scanFile(
|
||||
requireContext(),
|
||||
|
@ -561,69 +521,32 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
_binding = null
|
||||
}
|
||||
|
||||
class ListPathsAsyncTask(context: Context?, callback: OnPathsListedCallback) :
|
||||
ListingFilesDialogAsyncTask<ListPathsAsyncTask.LoadingInfo, String?, Array<String?>>(
|
||||
context
|
||||
private suspend fun listPaths(
|
||||
file: File,
|
||||
fileFilter: FileFilter,
|
||||
doOnPathListed: (paths: Array<String?>) -> Unit
|
||||
) {
|
||||
private val onPathsListedCallbackWeakReference: WeakReference<OnPathsListedCallback> =
|
||||
WeakReference(callback)
|
||||
|
||||
override fun doInBackground(vararg params: LoadingInfo): Array<String?> {
|
||||
return try {
|
||||
if (isCancelled || checkCallbackReference() == null) {
|
||||
return arrayOf()
|
||||
}
|
||||
val info = params[0]
|
||||
val paths = try {
|
||||
val paths: Array<String?>
|
||||
if (info.file.isDirectory) {
|
||||
val files = FileUtil.listFilesDeep(info.file, info.fileFilter)
|
||||
if (isCancelled || checkCallbackReference() == null) {
|
||||
return arrayOf()
|
||||
}
|
||||
if (file.isDirectory) {
|
||||
val files = FileUtil.listFilesDeep(file, fileFilter)
|
||||
paths = arrayOfNulls(files.size)
|
||||
for (i in files.indices) {
|
||||
val f = files[i]
|
||||
paths[i] = FileUtil.safeGetCanonicalPath(f)
|
||||
if (isCancelled || checkCallbackReference() == null) {
|
||||
return arrayOf()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
paths = arrayOfNulls(1)
|
||||
paths[0] = info.file.path
|
||||
paths[0] = file.path
|
||||
}
|
||||
paths
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
cancel(false)
|
||||
arrayOf()
|
||||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
doOnPathListed(paths)
|
||||
}
|
||||
|
||||
override fun onPostExecute(paths: Array<String?>) {
|
||||
super.onPostExecute(paths)
|
||||
checkCallbackReference()?.onPathsListed(paths)
|
||||
}
|
||||
|
||||
override fun onPreExecute() {
|
||||
super.onPreExecute()
|
||||
checkCallbackReference()
|
||||
}
|
||||
|
||||
private fun checkCallbackReference(): OnPathsListedCallback? {
|
||||
val callback = onPathsListedCallbackWeakReference.get()
|
||||
if (callback == null) {
|
||||
cancel(false)
|
||||
}
|
||||
return callback
|
||||
}
|
||||
|
||||
interface OnPathsListedCallback {
|
||||
fun onPathsListed(paths: Array<String?>)
|
||||
}
|
||||
|
||||
class LoadingInfo(val file: File, val fileFilter: FileFilter)
|
||||
|
||||
}
|
||||
|
||||
private class AsyncFileLoader(foldersFragment: FoldersFragment) :
|
||||
|
@ -651,87 +574,25 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
LinkedList()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private open class ListSongsAsyncTask(
|
||||
context: Context?,
|
||||
private val extra: Any?,
|
||||
callback: OnSongsListedCallback
|
||||
) : ListingFilesDialogAsyncTask<ListSongsAsyncTask.LoadingInfo, Void, List<Song>>(context) {
|
||||
private val callbackWeakReference = WeakReference(callback)
|
||||
private val contextWeakReference = WeakReference(context)
|
||||
override fun doInBackground(vararg params: LoadingInfo): List<Song> {
|
||||
return try {
|
||||
val info = params[0]
|
||||
val files = FileUtil.listFilesDeep(info.files, info.fileFilter)
|
||||
if (isCancelled || checkContextReference() == null || checkCallbackReference() == null) {
|
||||
return emptyList()
|
||||
}
|
||||
Collections.sort(files, info.fileComparator)
|
||||
val context = checkContextReference()
|
||||
if (isCancelled || context == null || checkCallbackReference() == null) {
|
||||
emptyList()
|
||||
} else FileUtil.matchFilesWithMediaStore(context, files)
|
||||
suspend fun listSongs(
|
||||
context: Context,
|
||||
files: List<File>,
|
||||
fileFilter: FileFilter,
|
||||
fileComparator: Comparator<File>,
|
||||
doOnSongsListed: (songs: List<Song>) -> Unit
|
||||
) {
|
||||
val songs = try {
|
||||
val fileList = FileUtil.listFilesDeep(files, fileFilter)
|
||||
Collections.sort(fileList, fileComparator)
|
||||
FileUtil.matchFilesWithMediaStore(context, fileList)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
cancel(false)
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPostExecute(songs: List<Song>) {
|
||||
super.onPostExecute(songs)
|
||||
checkCallbackReference()?.onSongsListed(songs, extra)
|
||||
}
|
||||
|
||||
override fun onPreExecute() {
|
||||
super.onPreExecute()
|
||||
checkCallbackReference()
|
||||
checkContextReference()
|
||||
}
|
||||
|
||||
private fun checkCallbackReference(): OnSongsListedCallback? {
|
||||
val callback = callbackWeakReference.get()
|
||||
if (callback == null) {
|
||||
cancel(false)
|
||||
}
|
||||
return callback
|
||||
}
|
||||
|
||||
private fun checkContextReference(): Context? {
|
||||
val context = contextWeakReference.get()
|
||||
if (context == null) {
|
||||
cancel(false)
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
interface OnSongsListedCallback {
|
||||
fun onSongsListed(songs: List<Song>, extra: Any?)
|
||||
}
|
||||
|
||||
class LoadingInfo(
|
||||
val files: List<File>,
|
||||
val fileFilter: FileFilter,
|
||||
val fileComparator: Comparator<File>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
abstract class ListingFilesDialogAsyncTask<Params, Progress, Result> internal constructor(
|
||||
context: Context?
|
||||
) :
|
||||
DialogAsyncTask<Params, Progress, Result>(context) {
|
||||
|
||||
override fun createDialog(context: Context): Dialog {
|
||||
return MaterialAlertDialogBuilder(context)
|
||||
.setTitle(R.string.listing_files)
|
||||
.setCancelable(false)
|
||||
.setView(R.layout.loading)
|
||||
.setOnCancelListener { cancel(false) }
|
||||
.setOnDismissListener { cancel(false) }
|
||||
.create()
|
||||
withContext(Dispatchers.Main) {
|
||||
doOnSongsListed(songs)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -772,7 +633,11 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
(!file.isHidden
|
||||
&& (file.isDirectory
|
||||
|| FileUtil.fileIsMimeType(file, "audio/*", MimeTypeMap.getSingleton())
|
||||
|| FileUtil.fileIsMimeType(file, "application/opus", MimeTypeMap.getSingleton())
|
||||
|| FileUtil.fileIsMimeType(
|
||||
file,
|
||||
"application/opus",
|
||||
MimeTypeMap.getSingleton()
|
||||
)
|
||||
|| FileUtil.fileIsMimeType(
|
||||
file,
|
||||
"application/ogg",
|
||||
|
@ -786,11 +651,11 @@ class FoldersFragment : AbsMainActivityFragment(R.layout.fragment_folder),
|
|||
val defaultStartDirectory: File
|
||||
get() {
|
||||
val musicDir =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)
|
||||
getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)
|
||||
val startFolder = if (musicDir.exists() && musicDir.isDirectory) {
|
||||
musicDir
|
||||
} else {
|
||||
val externalStorage = Environment.getExternalStorageDirectory()
|
||||
val externalStorage = getExternalStorageDirectory()
|
||||
if (externalStorage.exists() && externalStorage.isDirectory) {
|
||||
externalStorage
|
||||
} else {
|
||||
|
|
|
@ -53,10 +53,9 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
|
|||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true).addTarget(view)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
_binding = FragmentPlaylistDetailBinding.bind(view)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.addMusicServiceEventListener(detailsViewModel)
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
binding.container.setTransitionName("genre")
|
||||
binding.container.transitionName = "genre"
|
||||
genre = arguments.extraGenre
|
||||
binding.toolbar.title = arguments.extraGenre.name
|
||||
setupRecyclerView()
|
||||
|
@ -107,12 +106,11 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
|
|||
binding.recyclerView.setPadding(0, 0, 0, height)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_genre_detail, menu)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
return GenreMenuHelper.handleMenuClick(requireActivity(), genre, item)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import code.name.monkey.retromusic.interfaces.IMusicServiceEventListener
|
|||
import code.name.monkey.retromusic.model.Genre
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.repository.RealRepository
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Dispatchers.Main
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -44,7 +45,7 @@ class GenreDetailsViewModel(
|
|||
loadGenreSongs(genre)
|
||||
}
|
||||
|
||||
private fun loadGenreSongs(genre: Genre) = viewModelScope.launch {
|
||||
private fun loadGenreSongs(genre: Genre) = viewModelScope.launch(IO) {
|
||||
val songs = realRepository.getGenre(genre.id)
|
||||
withContext(Main) { _playListSongs.postValue(songs) }
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@ import android.view.Menu
|
|||
import android.view.MenuInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import androidx.activity.addCallback
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
|
@ -46,14 +45,10 @@ GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(),
|
|||
else
|
||||
adapter?.swapDataSet(listOf())
|
||||
}
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
remove()
|
||||
requireActivity().onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
override fun createLayoutManager(): LinearLayoutManager {
|
||||
return if (RetroUtil.isLandscape()) {
|
||||
return if (RetroUtil.isLandscape) {
|
||||
GridLayoutManager(activity, 4)
|
||||
} else {
|
||||
GridLayoutManager(activity, 2)
|
||||
|
@ -65,8 +60,8 @@ GenresFragment : AbsRecyclerViewFragment<GenreAdapter, LinearLayoutManager>(),
|
|||
return GenreAdapter(requireActivity(), dataSet, this)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateMenu(menu, inflater)
|
||||
menu.removeItem(R.id.action_grid_size)
|
||||
menu.removeItem(R.id.action_layout_type)
|
||||
menu.removeItem(R.id.action_sort_order)
|
||||
|
|
|
@ -20,7 +20,7 @@ import android.view.MenuInflater
|
|||
import android.view.MenuItem
|
||||
import android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM
|
||||
import android.view.View
|
||||
import androidx.activity.addCallback
|
||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.core.text.parseAsHtml
|
||||
import androidx.core.view.doOnLayout
|
||||
|
@ -29,7 +29,6 @@ import androidx.core.view.isVisible
|
|||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import code.name.monkey.appthemehelper.ThemeStore
|
||||
import code.name.monkey.appthemehelper.common.ATHToolbarActivity
|
||||
import code.name.monkey.appthemehelper.util.ColorUtil
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
|
@ -48,7 +47,7 @@ import code.name.monkey.retromusic.glide.RetroGlideExtension
|
|||
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.google.android.gms.cast.framework.CastButtonFactory
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
|
@ -67,7 +66,7 @@ class HomeFragment :
|
|||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
mainActivity.supportActionBar?.title = null
|
||||
setupListeners()
|
||||
binding.titleWelcome.text = String.format("%s", PreferenceUtil.userName)
|
||||
binding.titleWelcome.text = String.format("%s", userName)
|
||||
|
||||
enterTransition = MaterialFadeThrough().addTarget(binding.contentContainer)
|
||||
reenterTransition = MaterialFadeThrough().addTarget(binding.contentContainer)
|
||||
|
@ -77,12 +76,12 @@ class HomeFragment :
|
|||
layoutManager = LinearLayoutManager(mainActivity)
|
||||
adapter = homeAdapter
|
||||
}
|
||||
libraryViewModel.getHome().observe(viewLifecycleOwner) {
|
||||
homeAdapter.swapData(it)
|
||||
}
|
||||
libraryViewModel.getSuggestions().observe(viewLifecycleOwner) {
|
||||
loadSuggestions(it)
|
||||
}
|
||||
libraryViewModel.getHome().observe(viewLifecycleOwner) {
|
||||
homeAdapter.swapData(it)
|
||||
}
|
||||
|
||||
loadProfile()
|
||||
setupTitle()
|
||||
|
@ -92,10 +91,6 @@ class HomeFragment :
|
|||
binding.appBarLayout.statusBarForeground =
|
||||
MaterialShapeDrawable.createWithElevationOverlay(requireContext())
|
||||
binding.toolbar.drawNextToNavbar()
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
remove()
|
||||
requireActivity().onBackPressed()
|
||||
}
|
||||
view.doOnLayout {
|
||||
adjustPlaylistButtons()
|
||||
}
|
||||
|
@ -110,7 +105,6 @@ class HomeFragment :
|
|||
button.setLines(maxLineCount)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun setupListeners() {
|
||||
|
@ -195,8 +189,7 @@ class HomeFragment :
|
|||
binding.actionShuffle.elevatedAccentColor()
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_main, menu)
|
||||
menu.removeItem(R.id.action_grid_size)
|
||||
menu.removeItem(R.id.action_layout_type)
|
||||
|
@ -218,16 +211,12 @@ class HomeFragment :
|
|||
}
|
||||
|
||||
fun setSharedAxisXTransitions() {
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true).apply {
|
||||
addTarget(binding.root)
|
||||
}
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true).addTarget(CoordinatorLayout::class.java)
|
||||
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||
}
|
||||
|
||||
private fun setSharedAxisYTransitions() {
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Y, true).apply {
|
||||
addTarget(binding.root)
|
||||
}
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Y, true).addTarget(CoordinatorLayout::class.java)
|
||||
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Y, false)
|
||||
}
|
||||
|
||||
|
@ -246,7 +235,7 @@ class HomeFragment :
|
|||
binding.suggestions.image7,
|
||||
binding.suggestions.image8
|
||||
)
|
||||
val color = ThemeStore.accentColor(requireContext())
|
||||
val color = accentColor()
|
||||
binding.suggestions.message.apply {
|
||||
setTextColor(color)
|
||||
setOnClickListener {
|
||||
|
@ -285,7 +274,7 @@ class HomeFragment :
|
|||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.action_settings -> findNavController().navigate(
|
||||
R.id.settingsActivity,
|
||||
|
@ -301,11 +290,11 @@ class HomeFragment :
|
|||
"ShowCreatePlaylistDialog"
|
||||
)
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
override fun onPrepareMenu(menu: Menu) {
|
||||
super.onPrepareMenu(menu)
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), binding.toolbar)
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,6 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
|
|||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
mainActivity.setBottomNavVisibility(true)
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
mainActivity.supportActionBar?.title = null
|
||||
|
@ -87,13 +86,11 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
|
|||
}
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu) {
|
||||
super.onPrepareOptionsMenu(menu)
|
||||
override fun onPrepareMenu(menu: Menu) {
|
||||
ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), binding.toolbar)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_main, menu)
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||
requireContext(),
|
||||
|
@ -105,7 +102,7 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
|
|||
CastButtonFactory.setUpMediaRouteButton(requireContext(), menu, R.id.action_cast)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.action_settings -> findNavController().navigate(
|
||||
R.id.settingsActivity,
|
||||
|
@ -121,7 +118,7 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
|
|||
"ShowCreatePlaylistDialog"
|
||||
)
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
|
|
|
@ -66,12 +66,6 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentPlaylistDetailBinding.bind(view)
|
||||
when (args.type) {
|
||||
TOP_ARTISTS,
|
||||
RECENT_ARTISTS,
|
||||
|
@ -86,6 +80,13 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Y, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
_binding = FragmentPlaylistDetailBinding.bind(view)
|
||||
postponeEnterTransition()
|
||||
view.doOnPreDraw { startPostponedEnterTransition() }
|
||||
mainActivity.setSupportActionBar(binding.toolbar)
|
||||
binding.progressIndicator.hide()
|
||||
when (args.type) {
|
||||
|
@ -111,8 +112,6 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
})
|
||||
binding.appBarLayout.statusBarForeground =
|
||||
MaterialShapeDrawable.createWithElevationOverlay(requireContext())
|
||||
postponeEnterTransition()
|
||||
view.doOnPreDraw { startPostponedEnterTransition() }
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
if (!handleBackPress()) {
|
||||
remove()
|
||||
|
@ -237,10 +236,10 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
GridLayoutManager(requireContext(), gridCount(), GridLayoutManager.VERTICAL, false)
|
||||
|
||||
private fun gridCount(): Int {
|
||||
if (RetroUtil.isTablet()) {
|
||||
return if (RetroUtil.isLandscape()) 6 else 4
|
||||
if (RetroUtil.isTablet) {
|
||||
return if (RetroUtil.isLandscape) 6 else 4
|
||||
}
|
||||
return if (RetroUtil.isLandscape()) 4 else 2
|
||||
return if (RetroUtil.isLandscape) 4 else 2
|
||||
}
|
||||
|
||||
|
||||
|
@ -302,25 +301,25 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
|
|||
return cab as AttachedCab
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater)
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_clear_history, menu)
|
||||
if (showClearHistoryOption) {
|
||||
menu.findItem(R.id.action_clear_history).isVisible = true // Show Clear History option
|
||||
}
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
when (item.itemId) {
|
||||
R.id.action_clear_history -> {
|
||||
if (binding.recyclerView.adapter?.itemCount!! > 0) {
|
||||
libraryViewModel.clearHistory()
|
||||
|
||||
val snackBar =
|
||||
Snackbar.make(binding.container,
|
||||
Snackbar.make(
|
||||
binding.container,
|
||||
getString(R.string.history_cleared),
|
||||
Snackbar.LENGTH_LONG)
|
||||
Snackbar.LENGTH_LONG
|
||||
)
|
||||
.setAction(getString(R.string.history_undo_button)) {
|
||||
libraryViewModel.restoreHistory()
|
||||
}
|
||||
|
|
|
@ -40,10 +40,8 @@ import code.name.monkey.retromusic.activities.tageditor.TagWriter
|
|||
import code.name.monkey.retromusic.databinding.FragmentLyricsBinding
|
||||
import code.name.monkey.retromusic.databinding.FragmentNormalLyricsBinding
|
||||
import code.name.monkey.retromusic.databinding.FragmentSyncedLyricsBinding
|
||||
import code.name.monkey.retromusic.extensions.accentColor
|
||||
import code.name.monkey.retromusic.extensions.materialDialog
|
||||
import code.name.monkey.retromusic.extensions.textColorSecondary
|
||||
import code.name.monkey.retromusic.extensions.uri
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
|
||||
|
@ -52,12 +50,9 @@ import code.name.monkey.retromusic.model.AudioTagInfo
|
|||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.FileUtils
|
||||
import code.name.monkey.retromusic.util.LyricUtil
|
||||
import code.name.monkey.retromusic.util.RetroUtil
|
||||
import code.name.monkey.retromusic.util.UriUtil
|
||||
import com.afollestad.materialdialogs.input.input
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.tabs.TabLayoutMediator
|
||||
import com.google.android.material.transition.platform.MaterialContainerTransform
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jaudiotagger.audio.AudioFileIO
|
||||
|
@ -66,15 +61,12 @@ import java.io.File
|
|||
import java.io.FileOutputStream
|
||||
import java.util.*
|
||||
|
||||
class LyricsFragment : AbsMusicServiceFragment(R.layout.fragment_lyrics) {
|
||||
class LyricsFragment : AbsMainActivityFragment(R.layout.fragment_lyrics) {
|
||||
|
||||
private var _binding: FragmentLyricsBinding? = null
|
||||
private val binding get() = _binding!!
|
||||
private lateinit var song: Song
|
||||
|
||||
val mainActivity: MainActivity
|
||||
get() = activity as MainActivity
|
||||
|
||||
private lateinit var lyricsSectionsAdapter: LyricsSectionsAdapter
|
||||
|
||||
private val googleSearchLrcUrl: String
|
||||
|
@ -94,16 +86,6 @@ class LyricsFragment : AbsMusicServiceFragment(R.layout.fragment_lyrics) {
|
|||
return baseUrl
|
||||
}
|
||||
|
||||
private fun buildContainerTransform(): MaterialContainerTransform {
|
||||
val transform = MaterialContainerTransform()
|
||||
transform.setAllContainerColors(
|
||||
MaterialColors.getColor(requireView().findViewById(R.id.container), R.attr.colorSurface)
|
||||
)
|
||||
transform.addTarget(R.id.container)
|
||||
transform.duration = 300
|
||||
return transform
|
||||
}
|
||||
|
||||
private lateinit var normalLyricsLauncher: ActivityResultLauncher<IntentSenderRequest>
|
||||
private lateinit var newSyncedLyricsLauncher: ActivityResultLauncher<Intent>
|
||||
private lateinit var editSyncedLyricsLauncher: ActivityResultLauncher<IntentSenderRequest>
|
||||
|
@ -143,13 +125,12 @@ class LyricsFragment : AbsMusicServiceFragment(R.layout.fragment_lyrics) {
|
|||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
updateTitleSong()
|
||||
enterTransition = Fade()
|
||||
exitTransition = Fade()
|
||||
lyricsSectionsAdapter = LyricsSectionsAdapter(requireActivity())
|
||||
_binding = FragmentLyricsBinding.bind(view)
|
||||
binding.container.setTransitionName("lyrics")
|
||||
binding.container.transitionName = "lyrics"
|
||||
|
||||
setupWakelock()
|
||||
setupViews()
|
||||
|
@ -208,7 +189,7 @@ class LyricsFragment : AbsMusicServiceFragment(R.layout.fragment_lyrics) {
|
|||
requireActivity().window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
override fun onCreateMenu(menu: Menu, inflater: MenuInflater) {
|
||||
inflater.inflate(R.menu.menu_search, menu)
|
||||
ToolbarContentTintHelper.handleOnCreateOptionsMenu(
|
||||
requireContext(),
|
||||
|
@ -216,24 +197,18 @@ class LyricsFragment : AbsMusicServiceFragment(R.layout.fragment_lyrics) {
|
|||
menu,
|
||||
ATHToolbarActivity.getToolbarBackgroundColor(binding.toolbar)
|
||||
)
|
||||
return super.onCreateOptionsMenu(menu, inflater)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == android.R.id.home) {
|
||||
findNavController().navigateUp()
|
||||
return true
|
||||
}
|
||||
override fun onMenuItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == R.id.action_search) {
|
||||
RetroUtil.openUrl(
|
||||
requireActivity(), when (binding.lyricsPager.currentItem) {
|
||||
openUrl(when (binding.lyricsPager.currentItem) {
|
||||
0 -> syairSearchLrcUrl
|
||||
1 -> googleSearchLrcUrl
|
||||
else -> googleSearchLrcUrl
|
||||
}
|
||||
)
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
|
|||
view.setOnTouchListener(FlingPlayBackController(requireContext()))
|
||||
setUpMiniPlayer()
|
||||
|
||||
if (RetroUtil.isTablet()) {
|
||||
if (RetroUtil.isTablet) {
|
||||
binding.actionNext.show()
|
||||
binding.actionPrevious.show()
|
||||
} else {
|
||||
|
|
|
@ -15,16 +15,15 @@
|
|||
package code.name.monkey.retromusic.fragments.other
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.view.doOnPreDraw
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.fragment.app.Fragment
|
||||
|
@ -36,11 +35,12 @@ import code.name.monkey.retromusic.R
|
|||
import code.name.monkey.retromusic.databinding.FragmentUserInfoBinding
|
||||
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.util.ImageUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil
|
||||
import code.name.monkey.retromusic.util.PreferenceUtil.userName
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.load.DataSource
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
|
@ -55,9 +55,7 @@ import kotlinx.coroutines.Dispatchers
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
|
||||
class UserInfoFragment : Fragment() {
|
||||
|
||||
|
@ -85,7 +83,7 @@ class UserInfoFragment : Fragment() {
|
|||
|
||||
binding.nameContainer.accentColor()
|
||||
binding.next.accentColor()
|
||||
binding.name.setText(PreferenceUtil.userName)
|
||||
binding.name.setText(userName)
|
||||
|
||||
binding.userImage.setOnClickListener {
|
||||
showUserImageOptions()
|
||||
|
@ -98,14 +96,10 @@ class UserInfoFragment : Fragment() {
|
|||
binding.next.setOnClickListener {
|
||||
val nameString = binding.name.text.toString().trim { it <= ' ' }
|
||||
if (nameString.isEmpty()) {
|
||||
Toast.makeText(
|
||||
requireContext(),
|
||||
"Your name can't be empty!",
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
showToast("Your name can't be empty!")
|
||||
return@setOnClickListener
|
||||
}
|
||||
PreferenceUtil.userName = nameString
|
||||
userName = nameString
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
|
||||
|
@ -172,19 +166,14 @@ class UserInfoFragment : Fragment() {
|
|||
.into(binding.userImage)
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||
if (item.itemId == android.R.id.home) {
|
||||
findNavController().navigateUp()
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
private fun selectBannerImage() {
|
||||
ImagePicker.with(this)
|
||||
.compress(1440)
|
||||
.provider(ImageProvider.GALLERY)
|
||||
.crop(16f, 9f)
|
||||
.start(PICK_BANNER_REQUEST)
|
||||
.createIntent {
|
||||
startForBannerImageResult.launch(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun pickNewPhoto() {
|
||||
|
@ -192,21 +181,40 @@ class UserInfoFragment : Fragment() {
|
|||
.provider(ImageProvider.GALLERY)
|
||||
.cropSquare()
|
||||
.compress(1440)
|
||||
.start(PICK_IMAGE_REQUEST)
|
||||
.createIntent {
|
||||
startForProfileImageResult.launch(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (resultCode == Activity.RESULT_OK && requestCode == PICK_IMAGE_REQUEST) {
|
||||
val fileUri = data?.data
|
||||
fileUri?.let { setAndSaveUserImage(it) }
|
||||
} else if (resultCode == Activity.RESULT_OK && requestCode == PICK_BANNER_REQUEST) {
|
||||
val fileUri = data?.data
|
||||
fileUri?.let { setAndSaveBannerImage(it) }
|
||||
} else if (resultCode == ImagePicker.RESULT_ERROR) {
|
||||
Toast.makeText(requireContext(), ImagePicker.getError(data), Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
Toast.makeText(requireContext(), "Task Cancelled", Toast.LENGTH_SHORT).show()
|
||||
private val startForProfileImageResult =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
|
||||
saveImage(result) { fileUri ->
|
||||
setAndSaveUserImage(fileUri)
|
||||
}
|
||||
}
|
||||
|
||||
private val startForBannerImageResult =
|
||||
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result: ActivityResult ->
|
||||
saveImage(result) { fileUri ->
|
||||
setAndSaveBannerImage(fileUri)
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveImage(result: ActivityResult, doIfResultOk: (uri: Uri) -> Unit) {
|
||||
val resultCode = result.resultCode
|
||||
val data = result.data
|
||||
when (resultCode) {
|
||||
Activity.RESULT_OK -> {
|
||||
data?.data?.let { uri ->
|
||||
doIfResultOk(uri)
|
||||
}
|
||||
}
|
||||
ImagePicker.RESULT_ERROR -> {
|
||||
showToast(ImagePicker.getError(data))
|
||||
}
|
||||
else -> {
|
||||
showToast("Task Cancelled")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,7 +253,7 @@ class UserInfoFragment : Fragment() {
|
|||
val file = File(appDir, fileName)
|
||||
var successful = false
|
||||
runCatching {
|
||||
BufferedOutputStream(FileOutputStream(file)).use {
|
||||
file.outputStream().buffered().use {
|
||||
successful = ImageUtil.resizeBitmap(bitmap, 2048)
|
||||
.compress(Bitmap.CompressFormat.WEBP, 100, it)
|
||||
}
|
||||
|
@ -254,7 +262,7 @@ class UserInfoFragment : Fragment() {
|
|||
}
|
||||
if (successful) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(requireContext(), "Updated", Toast.LENGTH_SHORT).show()
|
||||
showToast("Updated")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -293,9 +301,4 @@ class UserInfoFragment : Fragment() {
|
|||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val PICK_IMAGE_REQUEST = 9002
|
||||
private const val PICK_BANNER_REQUEST = 9004
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
|||
lifecycleScope.launchWhenStarted {
|
||||
viewPager.setPageTransformer(false, transformer)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateLyrics() {
|
||||
binding.lyricsView.setLabel(context?.getString(R.string.no_lyrics_found))
|
||||
|
@ -116,12 +116,11 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
|||
binding.viewPager.addOnPageChangeListener(this)
|
||||
val nps = PreferenceUtil.nowPlayingScreen
|
||||
|
||||
val metrics = resources.displayMetrics
|
||||
val ratio = metrics.heightPixels.toFloat() / metrics.widthPixels.toFloat()
|
||||
|
||||
if (nps == Full || nps == Classic || nps == Fit || nps == Gradient) {
|
||||
binding.viewPager.offscreenPageLimit = 2
|
||||
} else if (PreferenceUtil.isCarouselEffect) {
|
||||
val metrics = resources.displayMetrics
|
||||
val ratio = metrics.heightPixels.toFloat() / metrics.widthPixels.toFloat()
|
||||
binding.viewPager.clipToPadding = false
|
||||
val padding =
|
||||
if (ratio >= 1.777f) {
|
||||
|
@ -281,12 +280,12 @@ class PlayerAlbumCoverFragment : AbsMusicServiceFragment(R.layout.fragment_playe
|
|||
setLRCViewColors(
|
||||
when (PreferenceUtil.nowPlayingScreen) {
|
||||
Adaptive, Fit, Plain, Simple -> surfaceColor()
|
||||
Flat, Normal -> if (PreferenceUtil.isAdaptiveColor) {
|
||||
Flat, Normal, Material -> if (PreferenceUtil.isAdaptiveColor) {
|
||||
color.backgroundColor
|
||||
} else {
|
||||
surfaceColor()
|
||||
}
|
||||
Color ,Classic -> color.backgroundColor
|
||||
Color, Classic -> color.backgroundColor
|
||||
Blur -> Color.BLACK
|
||||
else -> surfaceColor()
|
||||
}
|
||||
|
|
|
@ -48,9 +48,9 @@ class AdaptiveFragment : AbsPlayerFragment(R.layout.fragment_adaptive_player) {
|
|||
|
||||
private fun setUpSubFragments() {
|
||||
playbackControlsFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as AdaptivePlaybackControlsFragment
|
||||
whichFragment(R.id.playbackControlsFragment) as AdaptivePlaybackControlsFragment
|
||||
val playerAlbumCoverFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||
whichFragment(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||
playerAlbumCoverFragment.apply {
|
||||
removeSlideEffect()
|
||||
setCallbacks(this@AdaptiveFragment)
|
||||
|
|
|
@ -27,6 +27,7 @@ import code.name.monkey.retromusic.NEW_BLUR_AMOUNT
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentBlurBinding
|
||||
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.*
|
||||
|
@ -62,10 +63,9 @@ class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur),
|
|||
}
|
||||
|
||||
private fun setUpSubFragments() {
|
||||
playbackControlsFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as BlurPlaybackControlsFragment
|
||||
val playerAlbumCoverFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||
playbackControlsFragment = whichFragment(R.id.playbackControlsFragment)
|
||||
val playerAlbumCoverFragment: PlayerAlbumCoverFragment =
|
||||
whichFragment(R.id.playerAlbumCoverFragment)
|
||||
playerAlbumCoverFragment.setCallbacks(this)
|
||||
}
|
||||
|
||||
|
@ -141,6 +141,7 @@ class BlurPlayerFragment : AbsPlayerFragment(R.layout.fragment_blur),
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
lastRequest = null
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.registerOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
|
|
@ -22,9 +22,9 @@ import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentCardPlayerBinding
|
||||
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.fragments.player.normal.PlayerFragment
|
||||
import code.name.monkey.retromusic.helper.MusicPlayerRemote
|
||||
import code.name.monkey.retromusic.model.Song
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
|
@ -87,10 +87,9 @@ class CardFragment : AbsPlayerFragment(R.layout.fragment_card_player) {
|
|||
}
|
||||
|
||||
private fun setUpSubFragments() {
|
||||
playbackControlsFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as CardPlaybackControlsFragment
|
||||
val playerAlbumCoverFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||
playbackControlsFragment = whichFragment(R.id.playbackControlsFragment)
|
||||
val playerAlbumCoverFragment: PlayerAlbumCoverFragment =
|
||||
whichFragment(R.id.playerAlbumCoverFragment)
|
||||
playerAlbumCoverFragment.setCallbacks(this)
|
||||
playerAlbumCoverFragment.removeSlideEffect()
|
||||
}
|
||||
|
@ -117,14 +116,4 @@ class CardFragment : AbsPlayerFragment(R.layout.fragment_card_player) {
|
|||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun newInstance(): PlayerFragment {
|
||||
val args = Bundle()
|
||||
val fragment = PlayerFragment()
|
||||
fragment.arguments = args
|
||||
return fragment
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import code.name.monkey.retromusic.NEW_BLUR_AMOUNT
|
|||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.databinding.FragmentCardBlurPlayerBinding
|
||||
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.fragments.player.normal.PlayerFragment
|
||||
|
@ -98,8 +99,8 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
|
|||
|
||||
private fun setUpSubFragments() {
|
||||
playbackControlsFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playbackControlsFragment) as CardBlurPlaybackControlsFragment
|
||||
(childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment?)?.setCallbacks(
|
||||
whichFragment(R.id.playbackControlsFragment) as CardBlurPlaybackControlsFragment
|
||||
(whichFragment(R.id.playerAlbumCoverFragment) as? PlayerAlbumCoverFragment)?.setCallbacks(
|
||||
this
|
||||
)
|
||||
}
|
||||
|
@ -153,6 +154,7 @@ class CardBlurFragment : AbsPlayerFragment(R.layout.fragment_card_blur_player),
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
lastRequest = null
|
||||
PreferenceManager.getDefaultSharedPreferences(requireContext())
|
||||
.registerOnSharedPreferenceChangeListener(this)
|
||||
}
|
||||
|
|
|
@ -166,6 +166,7 @@ class CirclePlayerFragment : AbsPlayerFragment(R.layout.fragment_circle_player),
|
|||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
lastRequest = null
|
||||
progressViewUpdateHelper.start()
|
||||
if (audioVolumeObserver == null) {
|
||||
audioVolumeObserver = AudioVolumeObserver(requireActivity())
|
||||
|
|
|
@ -32,13 +32,9 @@ import code.name.monkey.appthemehelper.util.ColorUtil
|
|||
import code.name.monkey.appthemehelper.util.TintHelper
|
||||
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
|
||||
import code.name.monkey.retromusic.R
|
||||
import code.name.monkey.retromusic.RetroBottomSheetBehavior
|
||||
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
|
||||
import code.name.monkey.retromusic.databinding.FragmentClassicPlayerBinding
|
||||
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.surfaceColor
|
||||
import code.name.monkey.retromusic.extensions.*
|
||||
import code.name.monkey.retromusic.fragments.MusicSeekSkipTouchListener
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerControlsFragment
|
||||
import code.name.monkey.retromusic.fragments.base.AbsPlayerFragment
|
||||
|
@ -57,6 +53,7 @@ import code.name.monkey.retromusic.util.PreferenceUtil
|
|||
import code.name.monkey.retromusic.util.ViewUtil
|
||||
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior
|
||||
import com.google.android.material.bottomsheet.BottomSheetBehavior.from
|
||||
import com.google.android.material.card.MaterialCardView
|
||||
import com.google.android.material.shape.MaterialShapeDrawable
|
||||
import com.google.android.material.shape.ShapeAppearanceModel
|
||||
|
@ -88,7 +85,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
|
||||
private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||
mainActivity.getBottomSheetBehavior().setAllowDragging(false)
|
||||
mainActivity.getBottomSheetBehavior().isDraggable = false
|
||||
binding.playerQueueSheet.setContentPadding(
|
||||
binding.playerQueueSheet.contentPaddingLeft,
|
||||
(slideOffset * binding.statusBar.height).toInt(),
|
||||
|
@ -103,14 +100,14 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
when (newState) {
|
||||
BottomSheetBehavior.STATE_EXPANDED,
|
||||
BottomSheetBehavior.STATE_DRAGGING -> {
|
||||
mainActivity.getBottomSheetBehavior().setAllowDragging(false)
|
||||
mainActivity.getBottomSheetBehavior().isDraggable = false
|
||||
}
|
||||
BottomSheetBehavior.STATE_COLLAPSED -> {
|
||||
resetToCurrentPosition()
|
||||
mainActivity.getBottomSheetBehavior().setAllowDragging(true)
|
||||
mainActivity.getBottomSheetBehavior().isDraggable = true
|
||||
}
|
||||
else -> {
|
||||
mainActivity.getBottomSheetBehavior().setAllowDragging(true)
|
||||
mainActivity.getBottomSheetBehavior().isDraggable = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -131,8 +128,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
hideVolumeIfAvailable()
|
||||
setupRecyclerView()
|
||||
|
||||
val coverFragment =
|
||||
childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment
|
||||
val coverFragment: PlayerAlbumCoverFragment = whichFragment(R.id.playerAlbumCoverFragment)
|
||||
coverFragment.setCallbacks(this)
|
||||
|
||||
getQueuePanel().addBottomSheetCallback(bottomSheetCallbackList)
|
||||
|
@ -149,8 +145,8 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
binding.playerQueueSheet.background = shapeDrawable
|
||||
|
||||
binding.playerQueueSheet.setOnTouchListener { _, _ ->
|
||||
mainActivity.getBottomSheetBehavior().setAllowDragging(false)
|
||||
getQueuePanel().setAllowDragging(true)
|
||||
mainActivity.getBottomSheetBehavior().isDraggable = false
|
||||
getQueuePanel().isDraggable = true
|
||||
return@setOnTouchListener false
|
||||
}
|
||||
|
||||
|
@ -174,7 +170,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
}
|
||||
childFragmentManager.executePendingTransactions()
|
||||
volumeFragment =
|
||||
childFragmentManager.findFragmentById(R.id.volumeFragmentContainer) as VolumeFragment?
|
||||
whichFragment(R.id.volumeFragmentContainer) as VolumeFragment?
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -363,12 +359,12 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
||||
}
|
||||
|
||||
private fun getQueuePanel(): RetroBottomSheetBehavior<MaterialCardView> {
|
||||
return RetroBottomSheetBehavior.from(binding.playerQueueSheet) as RetroBottomSheetBehavior<MaterialCardView>
|
||||
private fun getQueuePanel(): BottomSheetBehavior<MaterialCardView> {
|
||||
return from(binding.playerQueueSheet)
|
||||
}
|
||||
|
||||
private fun setupPanel() {
|
||||
if (!binding.playerContainer.isLaidOut() || binding.playerContainer.isLayoutRequested) {
|
||||
if (!binding.playerContainer.isLaidOut || binding.playerContainer.isLayoutRequested) {
|
||||
binding.playerContainer.addOnLayoutChangeListener(this)
|
||||
return
|
||||
}
|
||||
|
@ -419,7 +415,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
|
|||
linearLayoutManager.scrollToPositionWithOffset(MusicPlayerRemote.position + 1, 0)
|
||||
}
|
||||
|
||||
fun setUpProgressSlider() {
|
||||
private fun setUpProgressSlider() {
|
||||
binding.playerControlsContainer.progressSlider.setOnSeekBarChangeListener(object :
|
||||
SimpleOnSeekbarChangeListener() {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue