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