Merge pull request #592 from naveensingh/sdk_and_viewbinding_migration
Migrate to View binding, SDK 34 and Version catalogs
This commit is contained in:
commit
afc92bf21c
68 changed files with 1361 additions and 1235 deletions
|
@ -1,93 +0,0 @@
|
|||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
|
||||
def keystorePropertiesFile = rootProject.file("keystore.properties")
|
||||
def keystoreProperties = new Properties()
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.simplemobiletools.musicplayer"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 33
|
||||
versionCode 114
|
||||
versionName "5.17.1"
|
||||
setProperty("archivesBaseName", "music-player")
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
release {
|
||||
keyAlias keystoreProperties['keyAlias']
|
||||
keyPassword keystoreProperties['keyPassword']
|
||||
storeFile file(keystoreProperties['storeFile'])
|
||||
storePassword keystoreProperties['storePassword']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
}
|
||||
release {
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions "variants"
|
||||
productFlavors {
|
||||
core {}
|
||||
fdroid {}
|
||||
prepaid {}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
coreLibraryDesugaringEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.github.SimpleMobileTools:Simple-Commons:f76d729b9d'
|
||||
implementation 'org.greenrobot:eventbus:3.3.1'
|
||||
implementation 'androidx.media:media:1.6.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.lifecycle:lifecycle-process:2.5.1'
|
||||
implementation 'androidx.media3:media3-session:1.1.1'
|
||||
implementation 'androidx.media3:media3-exoplayer:1.1.1'
|
||||
implementation 'com.google.android.material:material:1.6.1'
|
||||
implementation 'com.airbnb.android:lottie:3.6.1'
|
||||
implementation 'com.github.bjoernpetersen:m3u-parser:1.3.0'
|
||||
implementation 'me.grantland:autofittextview:0.2.1'
|
||||
coreLibraryDesugaring('com.android.tools:desugar_jdk_libs:1.1.5')
|
||||
|
||||
// higher versions of jaudiotagger not compatible with <= API 25 devices
|
||||
// https://bitbucket.org/ijabz/jaudiotagger/issues/149/some-nio-classes-are-unavailable-while
|
||||
implementation "net.jthink:jaudiotagger:2.2.5"
|
||||
kapt "androidx.room:room-compiler:2.5.2"
|
||||
implementation "androidx.room:room-runtime:2.5.2"
|
||||
annotationProcessor "androidx.room:room-compiler:2.5.2"
|
||||
}
|
109
app/build.gradle.kts
Normal file
109
app/build.gradle.kts
Normal file
|
@ -0,0 +1,109 @@
|
|||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
||||
import org.jetbrains.kotlin.konan.properties.Properties
|
||||
import java.io.FileInputStream
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.android)
|
||||
alias(libs.plugins.kotlinAndroid)
|
||||
alias(libs.plugins.ksp)
|
||||
}
|
||||
|
||||
val keystorePropertiesFile: File = rootProject.file("keystore.properties")
|
||||
val keystoreProperties = Properties()
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk = project.libs.versions.app.build.compileSDKVersion.get().toInt()
|
||||
|
||||
defaultConfig {
|
||||
applicationId = libs.versions.app.version.appId.get()
|
||||
minSdk = project.libs.versions.app.build.minimumSDK.get().toInt()
|
||||
targetSdk = project.libs.versions.app.build.targetSDK.get().toInt()
|
||||
versionName = project.libs.versions.app.version.versionName.get()
|
||||
versionCode = project.libs.versions.app.version.versionCode.get().toInt()
|
||||
setProperty("archivesBaseName", "music-player")
|
||||
vectorDrawables.useSupportLibrary = true
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
register("release") {
|
||||
keyAlias = keystoreProperties["keyAlias"] as String
|
||||
keyPassword = keystoreProperties["keyPassword"] as String
|
||||
storeFile = file(keystoreProperties["storeFile"] as String)
|
||||
storePassword = keystoreProperties["storePassword"] as String
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding = true
|
||||
buildConfig = true
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
applicationIdSuffix = ".debug"
|
||||
}
|
||||
release {
|
||||
isMinifyEnabled = true
|
||||
proguardFiles(
|
||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||
"proguard-rules.pro"
|
||||
)
|
||||
if (keystorePropertiesFile.exists()) {
|
||||
signingConfig = signingConfigs.getByName("release")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flavorDimensions.add("variants")
|
||||
productFlavors {
|
||||
register("core")
|
||||
register("fdroid")
|
||||
register("prepaid")
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
getByName("main").java.srcDirs("src/main/kotlin")
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
val currentJavaVersionFromLibs = JavaVersion.valueOf(libs.versions.app.build.javaVersion.get().toString())
|
||||
sourceCompatibility = currentJavaVersionFromLibs
|
||||
targetCompatibility = currentJavaVersionFromLibs
|
||||
isCoreLibraryDesugaringEnabled = true
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = project.libs.versions.app.build.kotlinJVMTarget.get()
|
||||
}
|
||||
|
||||
namespace = libs.versions.app.version.appId.get()
|
||||
|
||||
lint {
|
||||
checkReleaseBuilds = false
|
||||
abortOnError = false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.simple.mobile.tools.commons)
|
||||
implementation(libs.eventbus)
|
||||
implementation(libs.androidx.media)
|
||||
implementation(libs.androidx.swiperefreshlayout)
|
||||
implementation(libs.androidx.constraintlayout)
|
||||
implementation(libs.androidx.lifecycle.process)
|
||||
implementation(libs.androidx.media3.session)
|
||||
implementation(libs.androidx.media3.exoplayer)
|
||||
implementation(libs.lottie)
|
||||
implementation(libs.m3u.parser)
|
||||
implementation(libs.autofittextview)
|
||||
implementation(libs.jaudiotagger)
|
||||
coreLibraryDesugaring(libs.desugar.jdk.libs)
|
||||
|
||||
implementation(libs.bundles.room)
|
||||
ksp(libs.androidx.room.compiler)
|
||||
}
|
14
app/proguard-rules.pro
vendored
14
app/proguard-rules.pro
vendored
|
@ -8,15 +8,17 @@
|
|||
public <fields>;
|
||||
}
|
||||
|
||||
# Gson uses generic type information stored in a class file when working with
|
||||
# fields. Proguard removes such information by default, keep it.
|
||||
-keepattributes Signature
|
||||
# This is also needed for R8 in compat mode since multiple optimizations will
|
||||
# remove the generic signature such as class merging and argument removal.
|
||||
-keep class com.google.gson.reflect.TypeToken { *; }
|
||||
-keep class * extends com.google.gson.reflect.TypeToken
|
||||
|
||||
# EventBus
|
||||
-keepattributes *Annotation*
|
||||
-keepclassmembers class ** {
|
||||
@org.greenrobot.eventbus.Subscribe <methods>;
|
||||
}
|
||||
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
|
||||
|
||||
# Picasso
|
||||
-dontwarn javax.annotation.**
|
||||
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.*
|
||||
-dontwarn okhttp3.internal.platform.ConscryptPlatform
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
|
|
@ -10,29 +10,30 @@ import com.simplemobiletools.commons.helpers.NavigationIcon
|
|||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.adapters.AlbumsTracksAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.ActivityAlbumsBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.helpers.ALBUM
|
||||
import com.simplemobiletools.musicplayer.helpers.ARTIST
|
||||
import com.simplemobiletools.musicplayer.models.*
|
||||
import kotlinx.android.synthetic.main.activity_albums.*
|
||||
import kotlinx.android.synthetic.main.view_current_track_bar.current_track_bar
|
||||
|
||||
// Artists -> Albums -> Tracks
|
||||
class AlbumsActivity : SimpleMusicActivity() {
|
||||
|
||||
private val binding by viewBinding(ActivityAlbumsBinding::inflate)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
isMaterialActivity = true
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_albums)
|
||||
setContentView(binding.root)
|
||||
|
||||
updateMaterialActivityViews(albums_coordinator, albums_holder, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(albums_list, albums_toolbar)
|
||||
updateMaterialActivityViews(binding.albumsCoordinator, binding.albumsHolder, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(binding.albumsList, binding.albumsToolbar)
|
||||
|
||||
albums_fastscroller.updateColors(getProperPrimaryColor())
|
||||
binding.albumsFastscroller.updateColors(getProperPrimaryColor())
|
||||
|
||||
val artistType = object : TypeToken<Artist>() {}.type
|
||||
val artist = Gson().fromJson<Artist>(intent.getStringExtra(ARTIST), artistType)
|
||||
albums_toolbar.title = artist.title
|
||||
binding.albumsToolbar.title = artist.title
|
||||
|
||||
ensureBackgroundThread {
|
||||
val albums = audioHelper.getArtistAlbums(artist.id)
|
||||
|
@ -50,7 +51,7 @@ class AlbumsActivity : SimpleMusicActivity() {
|
|||
listItems.addAll(albumTracks)
|
||||
|
||||
runOnUiThread {
|
||||
AlbumsTracksAdapter(this, listItems, albums_list) {
|
||||
AlbumsTracksAdapter(this, listItems, binding.albumsList) {
|
||||
hideKeyboard()
|
||||
if (it is Album) {
|
||||
Intent(this, TracksActivity::class.java).apply {
|
||||
|
@ -63,25 +64,29 @@ class AlbumsActivity : SimpleMusicActivity() {
|
|||
val startIndex = albumTracks.indexOf(it as Track)
|
||||
prepareAndPlay(albumTracks, startIndex)
|
||||
} else {
|
||||
PermissionRequiredDialog(this, R.string.allow_notifications_music_player, { openNotificationSettings() })
|
||||
PermissionRequiredDialog(
|
||||
this,
|
||||
com.simplemobiletools.commons.R.string.allow_notifications_music_player,
|
||||
{ openNotificationSettings() }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.apply {
|
||||
albums_list.adapter = this
|
||||
binding.albumsList.adapter = this
|
||||
}
|
||||
|
||||
if (areSystemAnimationsEnabled) {
|
||||
albums_list.scheduleLayoutAnimation()
|
||||
binding.albumsList.scheduleLayoutAnimation()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setupCurrentTrackBar(current_track_bar)
|
||||
setupCurrentTrackBar(binding.currentTrackBar.root)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
setupToolbar(albums_toolbar, NavigationIcon.Arrow)
|
||||
setupToolbar(binding.albumsToolbar, NavigationIcon.Arrow)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,32 +12,35 @@ import com.simplemobiletools.commons.helpers.DARK_GREY
|
|||
import com.simplemobiletools.commons.helpers.NavigationIcon
|
||||
import com.simplemobiletools.commons.models.RadioItem
|
||||
import com.simplemobiletools.commons.views.MySeekBar
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.ActivityEqualizerBinding
|
||||
import com.simplemobiletools.musicplayer.databinding.EqualizerBandBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.helpers.EQUALIZER_PRESET_CUSTOM
|
||||
import com.simplemobiletools.musicplayer.playback.SimpleEqualizer
|
||||
import kotlinx.android.synthetic.main.activity_equalizer.*
|
||||
import kotlinx.android.synthetic.main.equalizer_band.view.*
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.log10
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class EqualizerActivity : SimpleActivity() {
|
||||
private var bands = HashMap<Short, Int>()
|
||||
private var bandSeekBars = ArrayList<MySeekBar>()
|
||||
|
||||
private val binding by viewBinding(ActivityEqualizerBinding::inflate)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
isMaterialActivity = true
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_equalizer)
|
||||
setContentView(binding.root)
|
||||
|
||||
updateMaterialActivityViews(equalizer_coordinator, equalizer_holder, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(equalizer_nested_scrollview, equalizer_toolbar)
|
||||
updateMaterialActivityViews(binding.equalizerCoordinator, binding.equalizerHolder, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(binding.equalizerNestedScrollview, binding.equalizerToolbar)
|
||||
initMediaPlayer()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
setupToolbar(equalizer_toolbar, NavigationIcon.Arrow)
|
||||
setupToolbar(binding.equalizerToolbar, NavigationIcon.Arrow)
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
|
@ -52,46 +55,46 @@ class EqualizerActivity : SimpleActivity() {
|
|||
|
||||
setupBands(equalizer)
|
||||
setupPresets(equalizer)
|
||||
updateTextColors(equalizer_holder)
|
||||
updateTextColors(binding.equalizerHolder)
|
||||
|
||||
val presetTextColor = if (isWhiteTheme()) {
|
||||
DARK_GREY
|
||||
} else {
|
||||
getProperPrimaryColor().getContrastColor()
|
||||
}
|
||||
equalizer_preset.setTextColor(presetTextColor)
|
||||
binding.equalizerPreset.setTextColor(presetTextColor)
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
private fun setupBands(equalizer: Equalizer) {
|
||||
val minValue = equalizer.bandLevelRange[0]
|
||||
val maxValue = equalizer.bandLevelRange[1]
|
||||
equalizer_label_right.text = "+${maxValue / 100}"
|
||||
equalizer_label_left.text = "${minValue / 100}"
|
||||
equalizer_label_0.text = (minValue + maxValue).toString()
|
||||
binding.equalizerLabelRight.text = "+${maxValue / 100}"
|
||||
binding.equalizerLabelLeft.text = "${minValue / 100}"
|
||||
binding.equalizerLabel0.text = (minValue + maxValue).toString()
|
||||
|
||||
bandSeekBars.clear()
|
||||
equalizer_bands_holder.removeAllViews()
|
||||
binding.equalizerBandsHolder.removeAllViews()
|
||||
|
||||
val bandType = object : TypeToken<HashMap<Short, Int>>() {}.type
|
||||
bands = Gson().fromJson<HashMap<Short, Int>>(config.equalizerBands, bandType) ?: HashMap()
|
||||
|
||||
for (band in 0 until equalizer.numberOfBands) {
|
||||
val frequency = equalizer.getCenterFreq(band.toShort()) / 1000
|
||||
val frequency = equalizer.getCenterFreq(band.toShort()) / 1000.0
|
||||
val formatted = formatFrequency(frequency)
|
||||
|
||||
layoutInflater.inflate(R.layout.equalizer_band, equalizer_bands_holder, false).apply {
|
||||
equalizer_bands_holder.addView(this)
|
||||
bandSeekBars.add(this.equalizer_band_seek_bar)
|
||||
this.equalizer_band_label.text = formatted
|
||||
this.equalizer_band_label.setTextColor(getProperTextColor())
|
||||
this.equalizer_band_seek_bar.max = maxValue - minValue
|
||||
EqualizerBandBinding.inflate(layoutInflater, binding.equalizerBandsHolder, false).apply {
|
||||
binding.equalizerBandsHolder.addView(root)
|
||||
bandSeekBars.add(equalizerBandSeekBar)
|
||||
equalizerBandLabel.text = formatted
|
||||
equalizerBandLabel.setTextColor(getProperTextColor())
|
||||
equalizerBandSeekBar.max = maxValue - minValue
|
||||
|
||||
this.equalizer_band_seek_bar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
equalizerBandSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
if (fromUser) {
|
||||
val newProgress = (progress / 100.0).roundToInt() * 100
|
||||
this@apply.equalizer_band_seek_bar.progress = newProgress
|
||||
equalizerBandSeekBar.progress = newProgress
|
||||
|
||||
val newValue = newProgress + minValue
|
||||
try {
|
||||
|
@ -109,7 +112,7 @@ class EqualizerActivity : SimpleActivity() {
|
|||
}
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar) {
|
||||
bands[band.toShort()] = this@apply.equalizer_band_seek_bar.progress
|
||||
bands[band.toShort()] = equalizerBandSeekBar.progress
|
||||
config.equalizerBands = Gson().toJson(bands)
|
||||
}
|
||||
})
|
||||
|
@ -118,7 +121,7 @@ class EqualizerActivity : SimpleActivity() {
|
|||
}
|
||||
|
||||
private fun draggingStarted(equalizer: Equalizer) {
|
||||
equalizer_preset.text = getString(R.string.custom)
|
||||
binding.equalizerPreset.text = getString(com.simplemobiletools.commons.R.string.custom)
|
||||
config.equalizerPreset = EQUALIZER_PRESET_CUSTOM
|
||||
for (band in 0 until equalizer.numberOfBands) {
|
||||
bands[band.toShort()] = bandSeekBars[band].progress
|
||||
|
@ -133,13 +136,13 @@ class EqualizerActivity : SimpleActivity() {
|
|||
config.equalizerPreset = EQUALIZER_PRESET_CUSTOM
|
||||
}
|
||||
|
||||
equalizer_preset.setOnClickListener {
|
||||
binding.equalizerPreset.setOnClickListener {
|
||||
val items = arrayListOf<RadioItem>()
|
||||
(0 until equalizer.numberOfPresets).mapTo(items) {
|
||||
RadioItem(it, equalizer.getPresetName(it.toShort()))
|
||||
}
|
||||
|
||||
items.add(RadioItem(EQUALIZER_PRESET_CUSTOM, getString(R.string.custom)))
|
||||
items.add(RadioItem(EQUALIZER_PRESET_CUSTOM, getString(com.simplemobiletools.commons.R.string.custom)))
|
||||
RadioGroupDialog(this, items, config.equalizerPreset) { presetId ->
|
||||
try {
|
||||
config.equalizerPreset = presetId as Int
|
||||
|
@ -154,7 +157,7 @@ class EqualizerActivity : SimpleActivity() {
|
|||
|
||||
private fun presetChanged(presetId: Int, equalizer: Equalizer) {
|
||||
if (presetId == EQUALIZER_PRESET_CUSTOM) {
|
||||
equalizer_preset.text = getString(R.string.custom)
|
||||
binding.equalizerPreset.text = getString(com.simplemobiletools.commons.R.string.custom)
|
||||
|
||||
for (band in 0 until equalizer.numberOfBands) {
|
||||
val minValue = equalizer.bandLevelRange[0]
|
||||
|
@ -173,9 +176,9 @@ class EqualizerActivity : SimpleActivity() {
|
|||
val presetName = equalizer.getPresetName(presetId.toShort())
|
||||
if (presetName.isEmpty()) {
|
||||
config.equalizerPreset = EQUALIZER_PRESET_CUSTOM
|
||||
equalizer_preset.text = getString(R.string.custom)
|
||||
binding.equalizerPreset.text = getString(com.simplemobiletools.commons.R.string.custom)
|
||||
} else {
|
||||
equalizer_preset.text = presetName
|
||||
binding.equalizerPreset.text = presetName
|
||||
}
|
||||
|
||||
equalizer.usePreset(presetId.toShort())
|
||||
|
@ -188,14 +191,14 @@ class EqualizerActivity : SimpleActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
// copypasted from the file size formatter, should be simplified
|
||||
private fun formatFrequency(value: Int): String {
|
||||
// copy-pasted from the file size formatter, should be simplified
|
||||
private fun formatFrequency(value: Double): String {
|
||||
if (value <= 0) {
|
||||
return "0 Hz"
|
||||
}
|
||||
|
||||
val units = arrayOf("Hz", "kHz", "gHz")
|
||||
val digitGroups = (Math.log10(value.toDouble()) / Math.log10(1000.0)).toInt()
|
||||
return "${DecimalFormat("#,##0.#").format(value / Math.pow(1000.0, digitGroups.toDouble()))} ${units[digitGroups]}"
|
||||
val digitGroups = (log10(value) / log10(1000.0)).toInt()
|
||||
return "${DecimalFormat("#,##0.#").format(value / 1000.0.pow(digitGroups.toDouble()))} ${units[digitGroups]}"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,38 +3,41 @@ package com.simplemobiletools.musicplayer.activities
|
|||
import android.os.Bundle
|
||||
import com.simplemobiletools.commons.extensions.beVisibleIf
|
||||
import com.simplemobiletools.commons.extensions.getProperTextColor
|
||||
import com.simplemobiletools.commons.extensions.viewBinding
|
||||
import com.simplemobiletools.commons.helpers.NavigationIcon
|
||||
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.adapters.ExcludedFoldersAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.ActivityExcludedFoldersBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import kotlinx.android.synthetic.main.activity_excluded_folders.*
|
||||
|
||||
class ExcludedFoldersActivity : SimpleActivity(), RefreshRecyclerViewListener {
|
||||
|
||||
private val binding by viewBinding(ActivityExcludedFoldersBinding::inflate)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
isMaterialActivity = true
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_excluded_folders)
|
||||
setContentView(binding.root)
|
||||
|
||||
updateMaterialActivityViews(excluded_folders_coordinator, excluded_folders_list, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(excluded_folders_list, excluded_folders_toolbar)
|
||||
updateMaterialActivityViews(binding.excludedFoldersCoordinator, binding.excludedFoldersList, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(binding.excludedFoldersList, binding.excludedFoldersToolbar)
|
||||
updateFolders()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
setupToolbar(excluded_folders_toolbar, NavigationIcon.Arrow)
|
||||
setupToolbar(binding.excludedFoldersToolbar, NavigationIcon.Arrow)
|
||||
}
|
||||
|
||||
private fun updateFolders() {
|
||||
val folders = config.excludedFolders.toMutableList() as ArrayList<String>
|
||||
excluded_folders_placeholder.apply {
|
||||
binding.excludedFoldersPlaceholder.apply {
|
||||
beVisibleIf(folders.isEmpty())
|
||||
setTextColor(getProperTextColor())
|
||||
}
|
||||
|
||||
val adapter = ExcludedFoldersAdapter(this, folders, this, excluded_folders_list) {}
|
||||
excluded_folders_list.adapter = adapter
|
||||
val adapter = ExcludedFoldersAdapter(this, folders, this, binding.excludedFoldersList) {}
|
||||
binding.excludedFoldersList.adapter = adapter
|
||||
}
|
||||
|
||||
override fun refreshItems() {
|
||||
|
|
|
@ -8,10 +8,9 @@ import android.graphics.drawable.Drawable
|
|||
import android.media.AudioManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.viewpager.widget.ViewPager
|
||||
import com.simplemobiletools.commons.databinding.BottomTablayoutItemBinding
|
||||
import com.simplemobiletools.commons.dialogs.FilePickerDialog
|
||||
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
|
@ -22,23 +21,16 @@ import com.simplemobiletools.commons.models.Release
|
|||
import com.simplemobiletools.musicplayer.BuildConfig
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.adapters.ViewPagerAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.ActivityMainBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.NewPlaylistDialog
|
||||
import com.simplemobiletools.musicplayer.dialogs.SelectPlaylistDialog
|
||||
import com.simplemobiletools.musicplayer.dialogs.SleepTimerCustomDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.fragments.MyViewPagerFragment
|
||||
import com.simplemobiletools.musicplayer.fragments.PlaylistsFragment
|
||||
import com.simplemobiletools.musicplayer.helpers.*
|
||||
import com.simplemobiletools.musicplayer.helpers.M3uImporter.ImportResult
|
||||
import com.simplemobiletools.musicplayer.models.Events
|
||||
import com.simplemobiletools.musicplayer.playback.CustomCommands
|
||||
import kotlinx.android.synthetic.main.activity_main.*
|
||||
import kotlinx.android.synthetic.main.fragment_albums.albums_fragment_holder
|
||||
import kotlinx.android.synthetic.main.fragment_artists.artists_fragment_holder
|
||||
import kotlinx.android.synthetic.main.fragment_folders.folders_fragment_holder
|
||||
import kotlinx.android.synthetic.main.fragment_genres.genres_fragment_holder
|
||||
import kotlinx.android.synthetic.main.fragment_playlists.playlists_fragment_holder
|
||||
import kotlinx.android.synthetic.main.fragment_tracks.tracks_fragment_holder
|
||||
import kotlinx.android.synthetic.main.view_current_track_bar.current_track_bar
|
||||
import me.grantland.widget.AutofitHelper
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.greenrobot.eventbus.Subscribe
|
||||
|
@ -52,22 +44,25 @@ class MainActivity : SimpleMusicActivity() {
|
|||
private var storedShowTabs = 0
|
||||
private var storedExcludedFolders = 0
|
||||
|
||||
private val binding by viewBinding(ActivityMainBinding::inflate)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
isMaterialActivity = true
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
setContentView(binding.root)
|
||||
appLaunched(BuildConfig.APPLICATION_ID)
|
||||
setupOptionsMenu()
|
||||
refreshMenuItems()
|
||||
updateMaterialActivityViews(main_coordinator, main_holder, useTransparentNavigation = false, useTopSearchMenu = true)
|
||||
updateMaterialActivityViews(binding.mainCoordinator, binding.mainHolder, useTransparentNavigation = false, useTopSearchMenu = true)
|
||||
storeStateVariables()
|
||||
setupTabs()
|
||||
setupCurrentTrackBar(binding.currentTrackBar.root)
|
||||
|
||||
handlePermission(getPermissionToRequest()) {
|
||||
if (it) {
|
||||
initActivity()
|
||||
} else {
|
||||
toast(R.string.no_storage_permissions)
|
||||
toast(com.simplemobiletools.commons.R.string.no_storage_permissions)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
@ -75,14 +70,6 @@ class MainActivity : SimpleMusicActivity() {
|
|||
volumeControlStream = AudioManager.STREAM_MUSIC
|
||||
checkWhatsNewDialog()
|
||||
checkAppOnSDCard()
|
||||
withPlayer {
|
||||
maybePreparePlayer(context = this@MainActivity) { success ->
|
||||
if (success) {
|
||||
updateCurrentTrackBar()
|
||||
broadcastUpdateWidgetState()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -94,17 +81,17 @@ class MainActivity : SimpleMusicActivity() {
|
|||
}
|
||||
|
||||
updateMenuColors()
|
||||
updateTextColors(main_holder)
|
||||
updateTextColors(binding.mainHolder)
|
||||
setupTabColors()
|
||||
val properTextColor = getProperTextColor()
|
||||
val properPrimaryColor = getProperPrimaryColor()
|
||||
sleep_timer_holder.background = ColorDrawable(getProperBackgroundColor())
|
||||
sleep_timer_stop.applyColorFilter(properTextColor)
|
||||
loading_progress_bar.setIndicatorColor(properPrimaryColor)
|
||||
loading_progress_bar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA)
|
||||
binding.sleepTimerHolder.background = ColorDrawable(getProperBackgroundColor())
|
||||
binding.sleepTimerStop.applyColorFilter(properTextColor)
|
||||
binding.loadingProgressBar.setIndicatorColor(properPrimaryColor)
|
||||
binding.loadingProgressBar.trackColor = properPrimaryColor.adjustAlpha(LOWER_ALPHA)
|
||||
|
||||
getAllFragments().forEach {
|
||||
it?.setupColors(properTextColor, properPrimaryColor)
|
||||
it.setupColors(properTextColor, properPrimaryColor)
|
||||
}
|
||||
|
||||
if (storedExcludedFolders != config.excludedFolders.hashCode()) {
|
||||
|
@ -115,7 +102,7 @@ class MainActivity : SimpleMusicActivity() {
|
|||
override fun onPause() {
|
||||
super.onPause()
|
||||
storeStateVariables()
|
||||
config.lastUsedViewPagerPage = view_pager.currentItem
|
||||
config.lastUsedViewPagerPage = binding.viewPager.currentItem
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
@ -124,38 +111,39 @@ class MainActivity : SimpleMusicActivity() {
|
|||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if (main_menu.isSearchOpen) {
|
||||
main_menu.closeSearch()
|
||||
if (binding.mainMenu.isSearchOpen) {
|
||||
binding.mainMenu.closeSearch()
|
||||
} else {
|
||||
super.onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshMenuItems() {
|
||||
main_menu.getToolbar().menu.apply {
|
||||
findItem(R.id.create_new_playlist).isVisible = getCurrentFragment() == playlists_fragment_holder
|
||||
findItem(R.id.create_playlist_from_folder).isVisible = getCurrentFragment() == playlists_fragment_holder
|
||||
findItem(R.id.import_playlist).isVisible = getCurrentFragment() == playlists_fragment_holder && isOreoPlus()
|
||||
findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(R.bool.hide_google_relations)
|
||||
binding.mainMenu.getToolbar().menu.apply {
|
||||
val isPlaylistFragment = getCurrentFragment() is PlaylistsFragment
|
||||
findItem(R.id.create_new_playlist).isVisible = isPlaylistFragment
|
||||
findItem(R.id.create_playlist_from_folder).isVisible = isPlaylistFragment
|
||||
findItem(R.id.import_playlist).isVisible = isPlaylistFragment && isOreoPlus()
|
||||
findItem(R.id.more_apps_from_us).isVisible = !resources.getBoolean(com.simplemobiletools.commons.R.bool.hide_google_relations)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupOptionsMenu() {
|
||||
main_menu.getToolbar().inflateMenu(R.menu.menu_main)
|
||||
main_menu.toggleHideOnScroll(false)
|
||||
main_menu.setupMenu()
|
||||
binding.mainMenu.getToolbar().inflateMenu(R.menu.menu_main)
|
||||
binding.mainMenu.toggleHideOnScroll(false)
|
||||
binding.mainMenu.setupMenu()
|
||||
|
||||
main_menu.onSearchClosedListener = {
|
||||
binding.mainMenu.onSearchClosedListener = {
|
||||
getAllFragments().forEach {
|
||||
it?.onSearchClosed()
|
||||
it.onSearchClosed()
|
||||
}
|
||||
}
|
||||
|
||||
main_menu.onSearchTextChangedListener = { text ->
|
||||
binding.mainMenu.onSearchTextChangedListener = { text ->
|
||||
getCurrentFragment()?.onSearchQueryChanged(text)
|
||||
}
|
||||
|
||||
main_menu.getToolbar().setOnMenuItemClickListener { menuItem ->
|
||||
binding.mainMenu.getToolbar().setOnMenuItemClickListener { menuItem ->
|
||||
when (menuItem.itemId) {
|
||||
R.id.sort -> showSortingDialog()
|
||||
R.id.rescan_media -> refreshAllFragments(showProgress = true)
|
||||
|
@ -175,7 +163,7 @@ class MainActivity : SimpleMusicActivity() {
|
|||
|
||||
private fun updateMenuColors() {
|
||||
updateStatusbarColor(getProperBackgroundColor())
|
||||
main_menu.updateColors()
|
||||
binding.mainMenu.updateColors()
|
||||
}
|
||||
|
||||
private fun storeStateVariables() {
|
||||
|
@ -191,28 +179,31 @@ class MainActivity : SimpleMusicActivity() {
|
|||
// trigger a scan first so that the fragments will accurately reflect the scanning state
|
||||
mediaScanner.scan()
|
||||
initFragments()
|
||||
sleep_timer_stop.setOnClickListener { stopSleepTimer() }
|
||||
binding.sleepTimerStop.setOnClickListener { stopSleepTimer() }
|
||||
|
||||
setupCurrentTrackBar(current_track_bar)
|
||||
refreshAllFragments()
|
||||
}
|
||||
|
||||
private fun refreshAllFragments(showProgress: Boolean = config.appRunCount == 1) {
|
||||
if (showProgress) {
|
||||
loading_progress_bar.show()
|
||||
binding.loadingProgressBar.show()
|
||||
}
|
||||
|
||||
handleNotificationPermission { granted ->
|
||||
mediaScanner.scan(progress = showProgress && granted) { complete ->
|
||||
runOnUiThread {
|
||||
getAllFragments().forEach {
|
||||
it?.setupFragment(this)
|
||||
it.setupFragment(this)
|
||||
}
|
||||
|
||||
if (complete) {
|
||||
loading_progress_bar.hide()
|
||||
binding.loadingProgressBar.hide()
|
||||
withPlayer {
|
||||
sendCommand(CustomCommands.RELOAD_CONTENT)
|
||||
if (currentMediaItem == null) {
|
||||
maybePreparePlayer()
|
||||
} else {
|
||||
sendCommand(CustomCommands.RELOAD_CONTENT)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -221,62 +212,61 @@ class MainActivity : SimpleMusicActivity() {
|
|||
}
|
||||
|
||||
private fun initFragments() {
|
||||
view_pager.adapter = ViewPagerAdapter(this)
|
||||
view_pager.offscreenPageLimit = tabsList.size - 1
|
||||
view_pager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
|
||||
binding.viewPager.adapter = ViewPagerAdapter(this)
|
||||
binding.viewPager.offscreenPageLimit = tabsList.size - 1
|
||||
binding.viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
|
||||
override fun onPageScrollStateChanged(state: Int) {}
|
||||
|
||||
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
main_tabs_holder.getTabAt(position)?.select()
|
||||
binding.mainTabsHolder.getTabAt(position)?.select()
|
||||
getAllFragments().forEach {
|
||||
it?.finishActMode()
|
||||
it.finishActMode()
|
||||
}
|
||||
refreshMenuItems()
|
||||
}
|
||||
})
|
||||
view_pager.currentItem = config.lastUsedViewPagerPage
|
||||
binding.viewPager.currentItem = config.lastUsedViewPagerPage
|
||||
}
|
||||
|
||||
private fun setupTabs() {
|
||||
main_tabs_holder.removeAllTabs()
|
||||
tabsList.forEachIndexed { index, value ->
|
||||
if (config.showTabs and value != 0) {
|
||||
main_tabs_holder.newTab().setCustomView(R.layout.bottom_tablayout_item).apply {
|
||||
customView?.findViewById<ImageView>(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(value))
|
||||
customView?.findViewById<TextView>(R.id.tab_item_label)?.text = getTabLabel(value)
|
||||
AutofitHelper.create(customView?.findViewById(R.id.tab_item_label))
|
||||
main_tabs_holder.addTab(this)
|
||||
}
|
||||
binding.mainTabsHolder.removeAllTabs()
|
||||
getVisibleTabs().forEach { value ->
|
||||
binding.mainTabsHolder.newTab().setCustomView(com.simplemobiletools.commons.R.layout.bottom_tablayout_item).apply {
|
||||
val tabItemBinding = BottomTablayoutItemBinding.bind(customView!!)
|
||||
tabItemBinding.tabItemIcon.setImageDrawable(getTabIcon(value))
|
||||
tabItemBinding.tabItemLabel.text = getTabLabel(value)
|
||||
AutofitHelper.create(tabItemBinding.tabItemLabel)
|
||||
binding.mainTabsHolder.addTab(this)
|
||||
}
|
||||
}
|
||||
|
||||
main_tabs_holder.onTabSelectionChanged(
|
||||
binding.mainTabsHolder.onTabSelectionChanged(
|
||||
tabUnselectedAction = {
|
||||
updateBottomTabItemColors(it.customView, false)
|
||||
},
|
||||
tabSelectedAction = {
|
||||
main_menu.closeSearch()
|
||||
view_pager.currentItem = it.position
|
||||
binding.mainMenu.closeSearch()
|
||||
binding.viewPager.currentItem = it.position
|
||||
updateBottomTabItemColors(it.customView, true)
|
||||
}
|
||||
)
|
||||
|
||||
main_tabs_holder.beGoneIf(main_tabs_holder.tabCount == 1)
|
||||
binding.mainTabsHolder.beGoneIf(binding.mainTabsHolder.tabCount == 1)
|
||||
}
|
||||
|
||||
private fun setupTabColors() {
|
||||
val activeView = main_tabs_holder.getTabAt(view_pager.currentItem)?.customView
|
||||
val activeView = binding.mainTabsHolder.getTabAt(binding.viewPager.currentItem)?.customView
|
||||
updateBottomTabItemColors(activeView, true)
|
||||
|
||||
getInactiveTabIndexes(view_pager.currentItem).forEach { index ->
|
||||
val inactiveView = main_tabs_holder.getTabAt(index)?.customView
|
||||
getInactiveTabIndexes(binding.viewPager.currentItem).forEach { index ->
|
||||
val inactiveView = binding.mainTabsHolder.getTabAt(index)?.customView
|
||||
updateBottomTabItemColors(inactiveView, false)
|
||||
}
|
||||
|
||||
val bottomBarColor = getBottomNavigationBackgroundColor()
|
||||
main_tabs_holder.setBackgroundColor(bottomBarColor)
|
||||
binding.mainTabsHolder.setBackgroundColor(bottomBarColor)
|
||||
updateNavigationBarColor(bottomBarColor)
|
||||
}
|
||||
|
||||
|
@ -286,7 +276,7 @@ class MainActivity : SimpleMusicActivity() {
|
|||
val drawableId = when (position) {
|
||||
TAB_PLAYLISTS -> R.drawable.ic_playlist_vector
|
||||
TAB_FOLDERS -> R.drawable.ic_folders_vector
|
||||
TAB_ARTISTS -> R.drawable.ic_person_vector
|
||||
TAB_ARTISTS -> com.simplemobiletools.commons.R.drawable.ic_person_vector
|
||||
TAB_ALBUMS -> R.drawable.ic_album_vector
|
||||
TAB_GENRES -> R.drawable.ic_genre_vector
|
||||
else -> R.drawable.ic_music_note_vector
|
||||
|
@ -308,36 +298,6 @@ class MainActivity : SimpleMusicActivity() {
|
|||
return resources.getString(stringId)
|
||||
}
|
||||
|
||||
private fun getCurrentFragment(): MyViewPagerFragment? {
|
||||
val showTabs = config.showTabs
|
||||
val fragments = arrayListOf<MyViewPagerFragment>()
|
||||
if (showTabs and TAB_PLAYLISTS != 0) {
|
||||
fragments.add(playlists_fragment_holder)
|
||||
}
|
||||
|
||||
if (showTabs and TAB_FOLDERS != 0) {
|
||||
fragments.add(folders_fragment_holder)
|
||||
}
|
||||
|
||||
if (showTabs and TAB_ARTISTS != 0) {
|
||||
fragments.add(artists_fragment_holder)
|
||||
}
|
||||
|
||||
if (showTabs and TAB_ALBUMS != 0) {
|
||||
fragments.add(albums_fragment_holder)
|
||||
}
|
||||
|
||||
if (showTabs and TAB_TRACKS != 0) {
|
||||
fragments.add(tracks_fragment_holder)
|
||||
}
|
||||
|
||||
if (showTabs and TAB_GENRES != 0) {
|
||||
fragments.add(genres_fragment_holder)
|
||||
}
|
||||
|
||||
return fragments.getOrNull(view_pager.currentItem)
|
||||
}
|
||||
|
||||
private fun showSortingDialog() {
|
||||
getCurrentFragment()?.onSortOpen(this)
|
||||
}
|
||||
|
@ -386,7 +346,7 @@ class MainActivity : SimpleMusicActivity() {
|
|||
uri.scheme == "content" -> {
|
||||
val tempFile = getTempFile("imports", uri.path!!.getFilenameFromPath())
|
||||
if (tempFile == null) {
|
||||
toast(R.string.unknown_error_occurred)
|
||||
toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -401,7 +361,7 @@ class MainActivity : SimpleMusicActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
else -> toast(R.string.invalid_file_format)
|
||||
else -> toast(com.simplemobiletools.commons.R.string.invalid_file_format)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,7 +375,7 @@ class MainActivity : SimpleMusicActivity() {
|
|||
try {
|
||||
startActivityForResult(this, PICK_IMPORT_SOURCE_INTENT)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
toast(R.string.system_service_disabled, Toast.LENGTH_LONG)
|
||||
toast(com.simplemobiletools.commons.R.string.system_service_disabled, Toast.LENGTH_LONG)
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
}
|
||||
|
@ -449,21 +409,21 @@ class MainActivity : SimpleMusicActivity() {
|
|||
runOnUiThread {
|
||||
toast(
|
||||
when (result) {
|
||||
ImportResult.IMPORT_OK -> R.string.importing_successful
|
||||
ImportResult.IMPORT_PARTIAL -> R.string.importing_some_entries_failed
|
||||
else -> R.string.importing_failed
|
||||
ImportResult.IMPORT_OK -> com.simplemobiletools.commons.R.string.importing_successful
|
||||
ImportResult.IMPORT_PARTIAL -> com.simplemobiletools.commons.R.string.importing_some_entries_failed
|
||||
else -> com.simplemobiletools.commons.R.string.importing_failed
|
||||
}
|
||||
)
|
||||
|
||||
playlists_fragment_holder.setupFragment(this)
|
||||
getAdapter()?.getPlaylistsFragment()?.setupFragment(this)
|
||||
}
|
||||
}.importPlaylist(path, id)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showSleepTimer() {
|
||||
val minutes = getString(R.string.minutes_raw)
|
||||
val hour = resources.getQuantityString(R.plurals.hours, 1, 1)
|
||||
val minutes = getString(com.simplemobiletools.commons.R.string.minutes_raw)
|
||||
val hour = resources.getQuantityString(com.simplemobiletools.commons.R.plurals.hours, 1, 1)
|
||||
|
||||
val items = arrayListOf(
|
||||
RadioItem(5 * 60, "5 $minutes"),
|
||||
|
@ -475,12 +435,12 @@ class MainActivity : SimpleMusicActivity() {
|
|||
|
||||
if (items.none { it.id == config.lastSleepTimerSeconds }) {
|
||||
val lastSleepTimerMinutes = config.lastSleepTimerSeconds / 60
|
||||
val text = resources.getQuantityString(R.plurals.minutes, lastSleepTimerMinutes, lastSleepTimerMinutes)
|
||||
val text = resources.getQuantityString(com.simplemobiletools.commons.R.plurals.minutes, lastSleepTimerMinutes, lastSleepTimerMinutes)
|
||||
items.add(RadioItem(config.lastSleepTimerSeconds, text))
|
||||
}
|
||||
|
||||
items.sortBy { it.id }
|
||||
items.add(RadioItem(-1, getString(R.string.custom)))
|
||||
items.add(RadioItem(-1, getString(com.simplemobiletools.commons.R.string.custom)))
|
||||
|
||||
RadioGroupDialog(this, items, config.lastSleepTimerSeconds) {
|
||||
if (it as Int == -1) {
|
||||
|
@ -502,32 +462,29 @@ class MainActivity : SimpleMusicActivity() {
|
|||
}
|
||||
|
||||
private fun startSleepTimer() {
|
||||
sleep_timer_holder.fadeIn()
|
||||
binding.sleepTimerHolder.fadeIn()
|
||||
withPlayer {
|
||||
sendCommand(CustomCommands.TOGGLE_SLEEP_TIMER)
|
||||
}
|
||||
}
|
||||
|
||||
private fun stopSleepTimer() {
|
||||
sleep_timer_holder.fadeOut()
|
||||
binding.sleepTimerHolder.fadeOut()
|
||||
withPlayer {
|
||||
sendCommand(CustomCommands.TOGGLE_SLEEP_TIMER)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAllFragments() = arrayListOf(
|
||||
playlists_fragment_holder,
|
||||
folders_fragment_holder,
|
||||
artists_fragment_holder,
|
||||
albums_fragment_holder,
|
||||
tracks_fragment_holder,
|
||||
genres_fragment_holder
|
||||
)
|
||||
private fun getAdapter() = binding.viewPager.adapter as? ViewPagerAdapter
|
||||
|
||||
private fun getAllFragments() = getAdapter()?.getAllFragments().orEmpty()
|
||||
|
||||
private fun getCurrentFragment() = getAdapter()?.getCurrentFragment()
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun sleepTimerChanged(event: Events.SleepTimerChanged) {
|
||||
sleep_timer_value.text = event.seconds.getFormattedDuration()
|
||||
sleep_timer_holder.beVisible()
|
||||
binding.sleepTimerValue.text = event.seconds.getFormattedDuration()
|
||||
binding.sleepTimerHolder.beVisible()
|
||||
|
||||
if (event.seconds == 0) {
|
||||
finish()
|
||||
|
@ -536,12 +493,12 @@ class MainActivity : SimpleMusicActivity() {
|
|||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun playlistsUpdated(event: Events.PlaylistsUpdated) {
|
||||
playlists_fragment_holder?.setupFragment(this)
|
||||
getAdapter()?.getPlaylistsFragment()?.setupFragment(this)
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun tracksUpdated(event: Events.RefreshTracks) {
|
||||
tracks_fragment_holder?.setupFragment(this)
|
||||
getAdapter()?.getTracksFragment()?.setupFragment(this)
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
|
@ -564,14 +521,14 @@ class MainActivity : SimpleMusicActivity() {
|
|||
|
||||
val faqItems = arrayListOf(
|
||||
FAQItem(R.string.faq_1_title, R.string.faq_1_text),
|
||||
FAQItem(R.string.faq_1_title_commons, R.string.faq_1_text_commons),
|
||||
FAQItem(R.string.faq_4_title_commons, R.string.faq_4_text_commons),
|
||||
FAQItem(R.string.faq_9_title_commons, R.string.faq_9_text_commons)
|
||||
FAQItem(com.simplemobiletools.commons.R.string.faq_1_title_commons, com.simplemobiletools.commons.R.string.faq_1_text_commons),
|
||||
FAQItem(com.simplemobiletools.commons.R.string.faq_4_title_commons, com.simplemobiletools.commons.R.string.faq_4_text_commons),
|
||||
FAQItem(com.simplemobiletools.commons.R.string.faq_9_title_commons, com.simplemobiletools.commons.R.string.faq_9_text_commons)
|
||||
)
|
||||
|
||||
if (!resources.getBoolean(R.bool.hide_google_relations)) {
|
||||
faqItems.add(FAQItem(R.string.faq_2_title_commons, R.string.faq_2_text_commons))
|
||||
faqItems.add(FAQItem(R.string.faq_6_title_commons, R.string.faq_6_text_commons))
|
||||
if (!resources.getBoolean(com.simplemobiletools.commons.R.bool.hide_google_relations)) {
|
||||
faqItems.add(FAQItem(com.simplemobiletools.commons.R.string.faq_2_title_commons, com.simplemobiletools.commons.R.string.faq_2_text_commons))
|
||||
faqItems.add(FAQItem(com.simplemobiletools.commons.R.string.faq_6_title_commons, com.simplemobiletools.commons.R.string.faq_6_text_commons))
|
||||
}
|
||||
|
||||
startAboutActivity(R.string.app_name, licenses, BuildConfig.VERSION_NAME, faqItems, true)
|
||||
|
|
|
@ -8,40 +8,42 @@ import android.view.MenuItem
|
|||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.view.MenuItemCompat
|
||||
import androidx.media3.common.MediaItem
|
||||
import androidx.media3.common.Timeline
|
||||
import com.simplemobiletools.commons.extensions.areSystemAnimationsEnabled
|
||||
import com.simplemobiletools.commons.extensions.beGoneIf
|
||||
import com.simplemobiletools.commons.extensions.getProperPrimaryColor
|
||||
import com.simplemobiletools.commons.extensions.viewBinding
|
||||
import com.simplemobiletools.commons.helpers.NavigationIcon
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.adapters.QueueAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.ActivityQueueBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.NewPlaylistDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.helpers.RoomHelper
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import kotlinx.android.synthetic.main.activity_queue.*
|
||||
|
||||
class QueueActivity : SimpleControllerActivity() {
|
||||
private var searchMenuItem: MenuItem? = null
|
||||
private var isSearchOpen = false
|
||||
private var tracksIgnoringSearch = ArrayList<Track>()
|
||||
|
||||
private val binding by viewBinding(ActivityQueueBinding::inflate)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
isMaterialActivity = true
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_queue)
|
||||
setContentView(binding.root)
|
||||
setupOptionsMenu()
|
||||
updateMaterialActivityViews(queue_coordinator, queue_list, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(queue_list, queue_toolbar)
|
||||
updateMaterialActivityViews(binding.queueCoordinator, binding.queueList, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(binding.queueList, binding.queueToolbar)
|
||||
|
||||
setupAdapter()
|
||||
queue_fastscroller.updateColors(getProperPrimaryColor())
|
||||
binding.queueFastscroller.updateColors(getProperPrimaryColor())
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
setupToolbar(queue_toolbar, NavigationIcon.Arrow, searchMenuItem = searchMenuItem)
|
||||
setupToolbar(binding.queueToolbar, NavigationIcon.Arrow, searchMenuItem = searchMenuItem)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
|
@ -56,11 +58,9 @@ class QueueActivity : SimpleControllerActivity() {
|
|||
getAdapter()?.updateCurrentTrack()
|
||||
}
|
||||
|
||||
override fun onTimelineChanged(timeline: Timeline, reason: Int) = updateAdapter()
|
||||
|
||||
private fun setupOptionsMenu() {
|
||||
setupSearch(queue_toolbar.menu)
|
||||
queue_toolbar.setOnMenuItemClickListener { menuItem ->
|
||||
setupSearch(binding.queueToolbar.menu)
|
||||
binding.queueToolbar.setOnMenuItemClickListener { menuItem ->
|
||||
when (menuItem.itemId) {
|
||||
R.id.create_playlist_from_queue -> createPlaylistFromQueue()
|
||||
else -> return@setOnMenuItemClickListener false
|
||||
|
@ -111,28 +111,28 @@ class QueueActivity : SimpleControllerActivity() {
|
|||
private fun onSearchClosed() {
|
||||
val adapter = getAdapter() ?: return
|
||||
adapter.updateItems(tracksIgnoringSearch, forceUpdate = true)
|
||||
queue_placeholder.beGoneIf(tracksIgnoringSearch.isNotEmpty())
|
||||
binding.queuePlaceholder.beGoneIf(tracksIgnoringSearch.isNotEmpty())
|
||||
}
|
||||
|
||||
private fun onSearchQueryChanged(text: String) {
|
||||
val filtered = tracksIgnoringSearch.filter { it.title.contains(text, true) }.toMutableList() as ArrayList<Track>
|
||||
getAdapter()?.updateItems(filtered, text)
|
||||
queue_placeholder.beGoneIf(filtered.isNotEmpty())
|
||||
binding.queuePlaceholder.beGoneIf(filtered.isNotEmpty())
|
||||
}
|
||||
|
||||
private fun getAdapter(): QueueAdapter? {
|
||||
return queue_list.adapter as? QueueAdapter
|
||||
return binding.queueList.adapter as? QueueAdapter
|
||||
}
|
||||
|
||||
private fun setupAdapter() {
|
||||
if (getAdapter() == null) {
|
||||
withPlayer {
|
||||
val tracks = currentMediaItemsShuffled.toTracks().toMutableList() as ArrayList<Track>
|
||||
queue_list.adapter = QueueAdapter(
|
||||
binding.queueList.adapter = QueueAdapter(
|
||||
activity = this@QueueActivity,
|
||||
items = tracks,
|
||||
currentTrack = currentMediaItem?.toTrack(),
|
||||
recyclerView = queue_list
|
||||
recyclerView = binding.queueList
|
||||
) {
|
||||
withPlayer {
|
||||
val startIndex = currentMediaItems.indexOfTrack(it as Track)
|
||||
|
@ -144,26 +144,17 @@ class QueueActivity : SimpleControllerActivity() {
|
|||
}
|
||||
|
||||
if (areSystemAnimationsEnabled) {
|
||||
queue_list.scheduleLayoutAnimation()
|
||||
binding.queueList.scheduleLayoutAnimation()
|
||||
}
|
||||
|
||||
val currentPosition = shuffledMediaItemsIndices.indexOf(currentMediaItemIndex)
|
||||
if (currentPosition > 0) {
|
||||
queue_list.lazySmoothScroll(currentPosition)
|
||||
binding.queueList.lazySmoothScroll(currentPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateAdapter() {
|
||||
val adapter = getAdapter() ?: return
|
||||
withPlayer {
|
||||
val currentTracks = currentMediaItemsShuffled.toTracks() as ArrayList<Track>
|
||||
adapter.updateItems(currentTracks)
|
||||
queue_list.lazySmoothScroll(shuffledMediaItemsIndices.indexOf(currentMediaItemIndex))
|
||||
}
|
||||
}
|
||||
|
||||
private fun createPlaylistFromQueue() {
|
||||
NewPlaylistDialog(this) { newPlaylistId ->
|
||||
val tracks = ArrayList<Track>()
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.simplemobiletools.commons.helpers.isQPlus
|
|||
import com.simplemobiletools.commons.helpers.isTiramisuPlus
|
||||
import com.simplemobiletools.commons.models.RadioItem
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.ActivitySettingsBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.ManageVisibleTabsDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.extensions.sendCommand
|
||||
|
@ -17,24 +18,25 @@ import com.simplemobiletools.musicplayer.helpers.SHOW_FILENAME_ALWAYS
|
|||
import com.simplemobiletools.musicplayer.helpers.SHOW_FILENAME_IF_UNAVAILABLE
|
||||
import com.simplemobiletools.musicplayer.helpers.SHOW_FILENAME_NEVER
|
||||
import com.simplemobiletools.musicplayer.playback.CustomCommands
|
||||
import kotlinx.android.synthetic.main.activity_settings.*
|
||||
import java.util.Locale
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
class SettingsActivity : SimpleControllerActivity() {
|
||||
|
||||
private val binding by viewBinding(ActivitySettingsBinding::inflate)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
isMaterialActivity = true
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_settings)
|
||||
setContentView(binding.root)
|
||||
|
||||
updateMaterialActivityViews(settings_coordinator, settings_holder, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(settings_nested_scrollview, settings_toolbar)
|
||||
updateMaterialActivityViews(binding.settingsCoordinator, binding.settingsHolder, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(binding.settingsNestedScrollview, binding.settingsToolbar)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
setupToolbar(settings_toolbar, NavigationIcon.Arrow)
|
||||
setupToolbar(binding.settingsToolbar, NavigationIcon.Arrow)
|
||||
|
||||
setupPurchaseThankYou()
|
||||
setupCustomizeColors()
|
||||
|
@ -46,29 +48,29 @@ class SettingsActivity : SimpleControllerActivity() {
|
|||
setupSwapPrevNext()
|
||||
setupReplaceTitle()
|
||||
setupGaplessPlayback()
|
||||
updateTextColors(settings_nested_scrollview)
|
||||
updateTextColors(binding.settingsNestedScrollview)
|
||||
|
||||
arrayOf(settings_color_customization_section_label, settings_general_settings_label, settings_playback_section_label).forEach {
|
||||
arrayOf(binding.settingsColorCustomizationSectionLabel, binding.settingsGeneralSettingsLabel, binding.settingsPlaybackSectionLabel).forEach {
|
||||
it.setTextColor(getProperPrimaryColor())
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupPurchaseThankYou() {
|
||||
settings_purchase_thank_you_holder.beGoneIf(isOrWasThankYouInstalled())
|
||||
settings_purchase_thank_you_holder.setOnClickListener {
|
||||
private fun setupPurchaseThankYou() = binding.apply {
|
||||
settingsPurchaseThankYouHolder.beGoneIf(isOrWasThankYouInstalled())
|
||||
settingsPurchaseThankYouHolder.setOnClickListener {
|
||||
launchPurchaseThankYouIntent()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupCustomizeColors() {
|
||||
settings_color_customization_label.text = getCustomizeColorsString()
|
||||
settings_color_customization_holder.setOnClickListener {
|
||||
private fun setupCustomizeColors() = binding.apply {
|
||||
settingsColorCustomizationLabel.text = getCustomizeColorsString()
|
||||
settingsColorCustomizationHolder.setOnClickListener {
|
||||
handleCustomizeColorsClick()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupCustomizeWidgetColors() {
|
||||
settings_widget_color_customization_holder.setOnClickListener {
|
||||
binding.settingsWidgetColorCustomizationHolder.setOnClickListener {
|
||||
Intent(this, WidgetConfigureActivity::class.java).apply {
|
||||
putExtra(IS_CUSTOMIZING_COLORS, true)
|
||||
startActivity(this)
|
||||
|
@ -76,44 +78,44 @@ class SettingsActivity : SimpleControllerActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun setupUseEnglish() {
|
||||
settings_use_english_holder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus())
|
||||
settings_use_english.isChecked = config.useEnglish
|
||||
settings_use_english_holder.setOnClickListener {
|
||||
settings_use_english.toggle()
|
||||
config.useEnglish = settings_use_english.isChecked
|
||||
private fun setupUseEnglish() = binding.apply {
|
||||
settingsUseEnglishHolder.beVisibleIf((config.wasUseEnglishToggled || Locale.getDefault().language != "en") && !isTiramisuPlus())
|
||||
settingsUseEnglish.isChecked = config.useEnglish
|
||||
settingsUseEnglishHolder.setOnClickListener {
|
||||
settingsUseEnglish.toggle()
|
||||
config.useEnglish = settingsUseEnglish.isChecked
|
||||
exitProcess(0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupLanguage() {
|
||||
settings_language.text = Locale.getDefault().displayLanguage
|
||||
settings_language_holder.beVisibleIf(isTiramisuPlus())
|
||||
settings_language_holder.setOnClickListener {
|
||||
private fun setupLanguage() = binding.apply {
|
||||
settingsLanguage.text = Locale.getDefault().displayLanguage
|
||||
settingsLanguageHolder.beVisibleIf(isTiramisuPlus())
|
||||
settingsLanguageHolder.setOnClickListener {
|
||||
launchChangeAppLanguageIntent()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupSwapPrevNext() {
|
||||
settings_swap_prev_next.isChecked = config.swapPrevNext
|
||||
settings_swap_prev_next_holder.setOnClickListener {
|
||||
settings_swap_prev_next.toggle()
|
||||
config.swapPrevNext = settings_swap_prev_next.isChecked
|
||||
private fun setupSwapPrevNext() = binding.apply {
|
||||
settingsSwapPrevNext.isChecked = config.swapPrevNext
|
||||
settingsSwapPrevNextHolder.setOnClickListener {
|
||||
settingsSwapPrevNext.toggle()
|
||||
config.swapPrevNext = settingsSwapPrevNext.isChecked
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupReplaceTitle() {
|
||||
settings_show_filename.text = getReplaceTitleText()
|
||||
settings_show_filename_holder.setOnClickListener {
|
||||
private fun setupReplaceTitle() = binding.apply {
|
||||
settingsShowFilename.text = getReplaceTitleText()
|
||||
settingsShowFilenameHolder.setOnClickListener {
|
||||
val items = arrayListOf(
|
||||
RadioItem(SHOW_FILENAME_NEVER, getString(R.string.never)),
|
||||
RadioItem(SHOW_FILENAME_NEVER, getString(com.simplemobiletools.commons.R.string.never)),
|
||||
RadioItem(SHOW_FILENAME_IF_UNAVAILABLE, getString(R.string.title_is_not_available)),
|
||||
RadioItem(SHOW_FILENAME_ALWAYS, getString(R.string.always))
|
||||
RadioItem(SHOW_FILENAME_ALWAYS, getString(com.simplemobiletools.commons.R.string.always))
|
||||
)
|
||||
|
||||
RadioGroupDialog(this@SettingsActivity, items, config.showFilename) {
|
||||
config.showFilename = it as Int
|
||||
settings_show_filename.text = getReplaceTitleText()
|
||||
settingsShowFilename.text = getReplaceTitleText()
|
||||
refreshQueueAndTracks()
|
||||
}
|
||||
}
|
||||
|
@ -121,15 +123,15 @@ class SettingsActivity : SimpleControllerActivity() {
|
|||
|
||||
private fun getReplaceTitleText() = getString(
|
||||
when (config.showFilename) {
|
||||
SHOW_FILENAME_NEVER -> R.string.never
|
||||
SHOW_FILENAME_NEVER -> com.simplemobiletools.commons.R.string.never
|
||||
SHOW_FILENAME_IF_UNAVAILABLE -> R.string.title_is_not_available
|
||||
else -> R.string.always
|
||||
else -> com.simplemobiletools.commons.R.string.always
|
||||
}
|
||||
)
|
||||
|
||||
private fun setupManageShownTabs() {
|
||||
settings_manage_shown_tabs_holder.setOnClickListener {
|
||||
ManageVisibleTabsDialog(this) { result ->
|
||||
private fun setupManageShownTabs() = binding.apply {
|
||||
settingsManageShownTabsHolder.setOnClickListener {
|
||||
ManageVisibleTabsDialog(this@SettingsActivity) { result ->
|
||||
val tabsMask = config.showTabs
|
||||
if (tabsMask != result) {
|
||||
config.showTabs = result
|
||||
|
@ -142,17 +144,17 @@ class SettingsActivity : SimpleControllerActivity() {
|
|||
}
|
||||
|
||||
private fun setupManageExcludedFolders() {
|
||||
settings_manage_excluded_folders_holder.beVisibleIf(isQPlus())
|
||||
settings_manage_excluded_folders_holder.setOnClickListener {
|
||||
binding.settingsManageExcludedFoldersHolder.beVisibleIf(isQPlus())
|
||||
binding.settingsManageExcludedFoldersHolder.setOnClickListener {
|
||||
startActivity(Intent(this, ExcludedFoldersActivity::class.java))
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupGaplessPlayback() {
|
||||
settings_gapless_playback.isChecked = config.gaplessPlayback
|
||||
settings_gapless_playback_holder.setOnClickListener {
|
||||
settings_gapless_playback.toggle()
|
||||
config.gaplessPlayback = settings_gapless_playback.isChecked
|
||||
private fun setupGaplessPlayback() = binding.apply {
|
||||
settingsGaplessPlayback.isChecked = config.gaplessPlayback
|
||||
settingsGaplessPlaybackHolder.setOnClickListener {
|
||||
settingsGaplessPlayback.toggle()
|
||||
config.gaplessPlayback = settingsGaplessPlayback.isChecked
|
||||
withPlayer {
|
||||
sendCommand(CustomCommands.TOGGLE_SKIP_SILENCE)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import androidx.media3.session.MediaController
|
|||
import com.simplemobiletools.commons.extensions.toast
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.commons.helpers.isRPlus
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.helpers.EXTRA_NEXT_MEDIA_ID
|
||||
import com.simplemobiletools.musicplayer.helpers.SimpleMediaController
|
||||
|
@ -31,6 +30,7 @@ abstract class SimpleControllerActivity : SimpleActivity(), Player.Listener {
|
|||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
controller = SimpleMediaController.getInstance(this)
|
||||
maybePreparePlayer()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
|
@ -43,6 +43,13 @@ abstract class SimpleControllerActivity : SimpleActivity(), Player.Listener {
|
|||
controller.removeListener(this)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
maybePreparePlayer()
|
||||
}
|
||||
|
||||
open fun onPlayerPrepared(success: Boolean) {}
|
||||
|
||||
fun withPlayer(callback: MediaController.() -> Unit) = controller.withController(callback)
|
||||
|
||||
fun prepareAndPlay(tracks: List<Track>, startIndex: Int = 0, startPositionMs: Long = 0, startActivity: Boolean = true) {
|
||||
|
@ -61,6 +68,14 @@ abstract class SimpleControllerActivity : SimpleActivity(), Player.Listener {
|
|||
}
|
||||
}
|
||||
|
||||
fun maybePreparePlayer() {
|
||||
withPlayer {
|
||||
maybePreparePlayer(context = this@SimpleControllerActivity, callback = ::onPlayerPrepared)
|
||||
}
|
||||
}
|
||||
|
||||
fun togglePlayback() = withPlayer { togglePlayback() }
|
||||
|
||||
fun addTracksToQueue(tracks: List<Track>, callback: () -> Unit) {
|
||||
withPlayer {
|
||||
val currentMediaItemsIds = currentMediaItems.map { it.mediaId }
|
||||
|
@ -117,7 +132,7 @@ abstract class SimpleControllerActivity : SimpleActivity(), Player.Listener {
|
|||
EventBus.getDefault().post(Events.RefreshFragments())
|
||||
callback()
|
||||
} else {
|
||||
toast(R.string.unknown_error_occurred)
|
||||
toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -7,9 +7,7 @@ import androidx.media3.common.Player
|
|||
import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog
|
||||
import com.simplemobiletools.commons.extensions.hideKeyboard
|
||||
import com.simplemobiletools.commons.extensions.openNotificationSettings
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.extensions.isReallyPlaying
|
||||
import com.simplemobiletools.musicplayer.extensions.togglePlayback
|
||||
import com.simplemobiletools.musicplayer.views.CurrentTrackBar
|
||||
|
||||
/**
|
||||
|
@ -25,7 +23,7 @@ abstract class SimpleMusicActivity : SimpleControllerActivity(), Player.Listener
|
|||
|
||||
fun setupCurrentTrackBar(trackBar: CurrentTrackBar) {
|
||||
trackBarView = trackBar
|
||||
trackBarView?.initialize { withPlayer { togglePlayback() } }
|
||||
trackBarView?.initialize(togglePlayback = ::togglePlayback)
|
||||
trackBarView?.setOnClickListener {
|
||||
hideKeyboard()
|
||||
handleNotificationPermission { granted ->
|
||||
|
@ -34,13 +32,13 @@ abstract class SimpleMusicActivity : SimpleControllerActivity(), Player.Listener
|
|||
startActivity(this)
|
||||
}
|
||||
} else {
|
||||
PermissionRequiredDialog(this, R.string.allow_notifications_music_player, { openNotificationSettings() })
|
||||
PermissionRequiredDialog(this, com.simplemobiletools.commons.R.string.allow_notifications_music_player, { openNotificationSettings() })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateCurrentTrackBar() {
|
||||
private fun updateCurrentTrackBar() {
|
||||
trackBarView?.apply {
|
||||
withPlayer {
|
||||
updateColors()
|
||||
|
@ -50,6 +48,8 @@ abstract class SimpleMusicActivity : SimpleControllerActivity(), Player.Listener
|
|||
}
|
||||
}
|
||||
|
||||
override fun onPlayerPrepared(success: Boolean) = updateCurrentTrackBar()
|
||||
|
||||
@CallSuper
|
||||
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
||||
trackBarView?.updateCurrentTrack(mediaItem)
|
||||
|
|
|
@ -25,6 +25,7 @@ import com.bumptech.glide.request.RequestOptions
|
|||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.MEDIUM_ALPHA
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.ActivityTrackBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.fragments.PlaybackSpeedFragment
|
||||
import com.simplemobiletools.musicplayer.helpers.*
|
||||
|
@ -32,7 +33,6 @@ import com.simplemobiletools.musicplayer.interfaces.PlaybackSpeedListener
|
|||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import com.simplemobiletools.musicplayer.playback.CustomCommands
|
||||
import com.simplemobiletools.musicplayer.playback.PlaybackService
|
||||
import kotlinx.android.synthetic.main.activity_track.*
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.math.min
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
@ -46,46 +46,50 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val updateIntervalMillis = 500L
|
||||
|
||||
private val binding by viewBinding(ActivityTrackBinding::inflate)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
showTransparentTop = true
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_track)
|
||||
setContentView(binding.root)
|
||||
nextTrackPlaceholder = resources.getColoredDrawableWithColor(R.drawable.ic_headset, getProperTextColor())
|
||||
setupButtons()
|
||||
setupFlingListener()
|
||||
|
||||
(activity_track_appbar.layoutParams as ConstraintLayout.LayoutParams).topMargin = statusBarHeight
|
||||
activity_track_holder.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
activity_track_toolbar.setNavigationOnClickListener {
|
||||
finish()
|
||||
}
|
||||
binding.apply {
|
||||
(activityTrackAppbar.layoutParams as ConstraintLayout.LayoutParams).topMargin = statusBarHeight
|
||||
activityTrackHolder.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
|
||||
activityTrackToolbar.setNavigationOnClickListener {
|
||||
finish()
|
||||
}
|
||||
|
||||
isThirdPartyIntent = intent.action == Intent.ACTION_VIEW
|
||||
arrayOf(activity_track_toggle_shuffle, activity_track_previous, activity_track_next, activity_track_playback_setting).forEach {
|
||||
it.beInvisibleIf(isThirdPartyIntent)
|
||||
}
|
||||
isThirdPartyIntent = intent.action == Intent.ACTION_VIEW
|
||||
arrayOf(activityTrackToggleShuffle, activityTrackPrevious, activityTrackNext, activityTrackPlaybackSetting).forEach {
|
||||
it.beInvisibleIf(isThirdPartyIntent)
|
||||
}
|
||||
|
||||
if (isThirdPartyIntent) {
|
||||
initThirdPartyIntent()
|
||||
return
|
||||
}
|
||||
if (isThirdPartyIntent) {
|
||||
initThirdPartyIntent()
|
||||
return
|
||||
}
|
||||
|
||||
setupTrackInfo(PlaybackService.currentMediaItem)
|
||||
setupNextTrackInfo(PlaybackService.nextMediaItem)
|
||||
activity_track_play_pause.updatePlayPauseIcon(PlaybackService.isPlaying, getProperTextColor())
|
||||
updatePlayerState()
|
||||
setupTrackInfo(PlaybackService.currentMediaItem)
|
||||
setupNextTrackInfo(PlaybackService.nextMediaItem)
|
||||
activityTrackPlayPause.updatePlayPauseIcon(PlaybackService.isPlaying, getProperTextColor())
|
||||
updatePlayerState()
|
||||
|
||||
next_track_holder.background = ColorDrawable(getProperBackgroundColor())
|
||||
next_track_holder.setOnClickListener {
|
||||
startActivity(Intent(applicationContext, QueueActivity::class.java))
|
||||
nextTrackHolder.background = ColorDrawable(getProperBackgroundColor())
|
||||
nextTrackHolder.setOnClickListener {
|
||||
startActivity(Intent(applicationContext, QueueActivity::class.java))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
updateTextColors(activity_track_holder)
|
||||
activity_track_title.setTextColor(getProperTextColor())
|
||||
activity_track_artist.setTextColor(getProperTextColor())
|
||||
updateTextColors(binding.activityTrackHolder)
|
||||
binding.activityTrackTitle.setTextColor(getProperTextColor())
|
||||
binding.activityTrackArtist.setTextColor(getProperTextColor())
|
||||
updatePlayerState()
|
||||
updateTrackInfo()
|
||||
}
|
||||
|
@ -116,45 +120,52 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
val track = item?.toTrack() ?: return
|
||||
|
||||
setupTopArt(track)
|
||||
activity_track_title.text = track.title
|
||||
activity_track_artist.text = track.artist
|
||||
activity_track_title.setOnLongClickListener {
|
||||
copyToClipboard(activity_track_title.value)
|
||||
true
|
||||
}
|
||||
binding.apply {
|
||||
activityTrackTitle.text = track.title
|
||||
activityTrackArtist.text = track.artist
|
||||
activityTrackTitle.setOnLongClickListener {
|
||||
copyToClipboard(activityTrackTitle.value)
|
||||
true
|
||||
}
|
||||
|
||||
activity_track_artist.setOnLongClickListener {
|
||||
copyToClipboard(activity_track_artist.value)
|
||||
true
|
||||
}
|
||||
activityTrackArtist.setOnLongClickListener {
|
||||
copyToClipboard(activityTrackArtist.value)
|
||||
true
|
||||
}
|
||||
|
||||
activity_track_progressbar.max = track.duration
|
||||
activity_track_progress_max.text = track.duration.getFormattedDuration()
|
||||
activityTrackProgressbar.max = track.duration
|
||||
activityTrackProgressMax.text = track.duration.getFormattedDuration()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initThirdPartyIntent() {
|
||||
next_track_holder.beGone()
|
||||
getTrackFromUri(intent.data) {
|
||||
binding.nextTrackHolder.beGone()
|
||||
getTrackFromUri(intent.data) { track ->
|
||||
runOnUiThread {
|
||||
prepareAndPlay(listOf(it), startActivity = false)
|
||||
if (track != null) {
|
||||
prepareAndPlay(listOf(track), startActivity = false)
|
||||
} else {
|
||||
toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
|
||||
finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupButtons() {
|
||||
activity_track_toggle_shuffle.setOnClickListener { withPlayer { toggleShuffle() } }
|
||||
activity_track_previous.setOnClickListener { withPlayer { forceSeekToPrevious() } }
|
||||
activity_track_play_pause.setOnClickListener { withPlayer { togglePlayback() } }
|
||||
activity_track_next.setOnClickListener { withPlayer { forceSeekToNext() } }
|
||||
activity_track_progress_current.setOnClickListener { seekBack() }
|
||||
activity_track_progress_max.setOnClickListener { seekForward() }
|
||||
activity_track_playback_setting.setOnClickListener { togglePlaybackSetting() }
|
||||
activity_track_speed_click_area.setOnClickListener { showPlaybackSpeedPicker() }
|
||||
private fun setupButtons() = binding.apply {
|
||||
activityTrackToggleShuffle.setOnClickListener { withPlayer { toggleShuffle() } }
|
||||
activityTrackPrevious.setOnClickListener { withPlayer { forceSeekToPrevious() } }
|
||||
activityTrackPlayPause.setOnClickListener { togglePlayback() }
|
||||
activityTrackNext.setOnClickListener { withPlayer { forceSeekToNext() } }
|
||||
activityTrackProgressCurrent.setOnClickListener { seekBack() }
|
||||
activityTrackProgressMax.setOnClickListener { seekForward() }
|
||||
activityTrackPlaybackSetting.setOnClickListener { togglePlaybackSetting() }
|
||||
activityTrackSpeedClickArea.setOnClickListener { showPlaybackSpeedPicker() }
|
||||
setupShuffleButton()
|
||||
setupPlaybackSettingButton()
|
||||
setupSeekbar()
|
||||
|
||||
arrayOf(activity_track_previous, activity_track_play_pause, activity_track_next).forEach {
|
||||
arrayOf(activityTrackPrevious, activityTrackPlayPause, activityTrackNext).forEach {
|
||||
it.applyColorFilter(getProperTextColor())
|
||||
}
|
||||
}
|
||||
|
@ -162,11 +173,11 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
private fun setupNextTrackInfo(item: MediaItem?) {
|
||||
val track = item?.toTrack()
|
||||
if (track == null) {
|
||||
next_track_holder.beGone()
|
||||
binding.nextTrackHolder.beGone()
|
||||
return
|
||||
}
|
||||
|
||||
next_track_holder.beVisible()
|
||||
binding.nextTrackHolder.beVisible()
|
||||
val artist = if (track.artist.trim().isNotEmpty() && track.artist != MediaStore.UNKNOWN_STRING) {
|
||||
" • ${track.artist}"
|
||||
} else {
|
||||
|
@ -174,10 +185,10 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
next_track_label.text = "${getString(R.string.next_track)} ${track.title}$artist"
|
||||
binding.nextTrackLabel.text = "${getString(R.string.next_track)} ${track.title}$artist"
|
||||
|
||||
getTrackCoverArt(track) { coverArt ->
|
||||
val cornerRadius = resources.getDimension(R.dimen.rounded_corner_radius_small).toInt()
|
||||
val cornerRadius = resources.getDimension(com.simplemobiletools.commons.R.dimen.rounded_corner_radius_small).toInt()
|
||||
val wantedSize = resources.getDimension(R.dimen.song_image_size).toInt()
|
||||
|
||||
// change cover image manually only once loaded successfully to avoid blinking at fails and placeholders
|
||||
|
@ -187,12 +198,12 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
size = Size(wantedSize, wantedSize),
|
||||
onLoadFailed = {
|
||||
runOnUiThread {
|
||||
next_track_image.setImageDrawable(nextTrackPlaceholder)
|
||||
binding.nextTrackImage.setImageDrawable(nextTrackPlaceholder)
|
||||
}
|
||||
},
|
||||
onResourceReady = {
|
||||
runOnUiThread {
|
||||
next_track_image.setImageDrawable(it)
|
||||
binding.nextTrackImage.setImageDrawable(it)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -216,17 +227,17 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
placeholder.applyColorFilter(getProperTextColor())
|
||||
|
||||
runOnUiThread {
|
||||
activity_track_image.setImageDrawable(placeholder)
|
||||
binding.activityTrackImage.setImageDrawable(placeholder)
|
||||
}
|
||||
},
|
||||
onResourceReady = {
|
||||
val coverHeight = it.intrinsicHeight
|
||||
if (coverHeight > 0 && activity_track_image.height != coverHeight) {
|
||||
activity_track_image.layoutParams.height = coverHeight
|
||||
if (coverHeight > 0 && binding.activityTrackImage.height != coverHeight) {
|
||||
binding.activityTrackImage.layoutParams.height = coverHeight
|
||||
}
|
||||
|
||||
runOnUiThread {
|
||||
activity_track_image.setImageDrawable(it)
|
||||
binding.activityTrackImage.setImageDrawable(it)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -236,18 +247,20 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun setupFlingListener() {
|
||||
val flingListener = object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
|
||||
if (velocityY > 0 && velocityY > velocityX && e2.y - e1.y > SWIPE_DOWN_THRESHOLD) {
|
||||
finish()
|
||||
activity_track_top_shadow.animate().alpha(0f).start()
|
||||
overridePendingTransition(0, R.anim.slide_down)
|
||||
override fun onFling(e1: MotionEvent?, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
|
||||
if (e1 != null) {
|
||||
if (velocityY > 0 && velocityY > velocityX && e2.y - e1.y > SWIPE_DOWN_THRESHOLD) {
|
||||
finish()
|
||||
binding.activityTrackTopShadow.animate().alpha(0f).start()
|
||||
overridePendingTransition(0, com.simplemobiletools.commons.R.anim.slide_down)
|
||||
}
|
||||
}
|
||||
return super.onFling(e1, e2, velocityX, velocityY)
|
||||
}
|
||||
}
|
||||
|
||||
val gestureDetector = GestureDetectorCompat(this, flingListener)
|
||||
activity_track_holder.setOnTouchListener { v, event ->
|
||||
binding.activityTrackHolder.setOnTouchListener { _, event ->
|
||||
gestureDetector.onTouchEvent(event)
|
||||
true
|
||||
}
|
||||
|
@ -265,7 +278,7 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
}
|
||||
|
||||
private fun setupShuffleButton(isShuffleEnabled: Boolean = config.isShuffleEnabled) {
|
||||
activity_track_toggle_shuffle.apply {
|
||||
binding.activityTrackToggleShuffle.apply {
|
||||
applyColorFilter(if (isShuffleEnabled) getProperPrimaryColor() else getProperTextColor())
|
||||
alpha = if (isShuffleEnabled) 1f else MEDIUM_ALPHA
|
||||
contentDescription = getString(if (isShuffleEnabled) R.string.disable_shuffle else R.string.enable_shuffle)
|
||||
|
@ -273,12 +286,12 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
}
|
||||
|
||||
private fun seekBack() {
|
||||
activity_track_progressbar.progress += -SEEK_INTERVAL_S
|
||||
binding.activityTrackProgressbar.progress += -SEEK_INTERVAL_S
|
||||
withPlayer { seekBack() }
|
||||
}
|
||||
|
||||
private fun seekForward() {
|
||||
activity_track_progressbar.progress += SEEK_INTERVAL_S
|
||||
binding.activityTrackProgressbar.progress += SEEK_INTERVAL_S
|
||||
withPlayer { seekForward() }
|
||||
}
|
||||
|
||||
|
@ -292,8 +305,14 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
}
|
||||
}
|
||||
|
||||
private fun maybeUpdatePlaybackSettingButton(playbackSetting: PlaybackSetting) {
|
||||
if (config.playbackSetting != PlaybackSetting.STOP_AFTER_CURRENT_TRACK) {
|
||||
setupPlaybackSettingButton(playbackSetting)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupPlaybackSettingButton(playbackSetting: PlaybackSetting = config.playbackSetting) {
|
||||
activity_track_playback_setting.apply {
|
||||
binding.activityTrackPlaybackSetting.apply {
|
||||
contentDescription = getString(playbackSetting.contentDescriptionStringRes)
|
||||
setImageResource(playbackSetting.iconRes)
|
||||
|
||||
|
@ -305,13 +324,13 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
}
|
||||
|
||||
private fun setupSeekbar() {
|
||||
activity_track_speed_icon.applyColorFilter(getProperTextColor())
|
||||
binding.activityTrackSpeedIcon.applyColorFilter(getProperTextColor())
|
||||
updatePlaybackSpeed(config.playbackSpeed)
|
||||
|
||||
activity_track_progressbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
binding.activityTrackProgressbar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
|
||||
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
|
||||
val formattedProgress = progress.getFormattedDuration()
|
||||
activity_track_progress_current.text = formattedProgress
|
||||
binding.activityTrackProgressCurrent.text = formattedProgress
|
||||
}
|
||||
|
||||
override fun onStartTrackingTouch(seekBar: SeekBar) {}
|
||||
|
@ -330,15 +349,15 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
|
||||
override fun updatePlaybackSpeed(speed: Float) {
|
||||
val isSlow = speed < 1f
|
||||
if (isSlow != activity_track_speed.tag as? Boolean) {
|
||||
activity_track_speed.tag = isSlow
|
||||
if (isSlow != binding.activityTrackSpeed.tag as? Boolean) {
|
||||
binding.activityTrackSpeed.tag = isSlow
|
||||
|
||||
val drawableId = if (isSlow) R.drawable.ic_playback_speed_slow_vector else R.drawable.ic_playback_speed_vector
|
||||
activity_track_speed_icon.setImageDrawable(resources.getDrawable(drawableId))
|
||||
binding.activityTrackSpeedIcon.setImageDrawable(resources.getDrawable(drawableId))
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
activity_track_speed.text = "${DecimalFormat("#.##").format(speed)}x"
|
||||
binding.activityTrackSpeed.text = "${DecimalFormat("#.##").format(speed)}x"
|
||||
withPlayer {
|
||||
setPlaybackSpeed(speed)
|
||||
}
|
||||
|
@ -354,7 +373,7 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
|
||||
override fun onIsPlayingChanged(isPlaying: Boolean) = updatePlayerState()
|
||||
|
||||
override fun onRepeatModeChanged(repeatMode: Int) = setupPlaybackSettingButton(getPlaybackSetting(repeatMode))
|
||||
override fun onRepeatModeChanged(repeatMode: Int) = maybeUpdatePlaybackSettingButton(getPlaybackSetting(repeatMode))
|
||||
|
||||
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) = setupShuffleButton(shuffleModeEnabled)
|
||||
|
||||
|
@ -363,7 +382,7 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
if (mediaItem == null) {
|
||||
finish()
|
||||
} else {
|
||||
activity_track_progressbar.progress = 0
|
||||
binding.activityTrackProgressbar.progress = 0
|
||||
updateTrackInfo()
|
||||
}
|
||||
}
|
||||
|
@ -387,7 +406,7 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
updateProgress(currentPosition)
|
||||
updatePlayPause(isPlaying)
|
||||
setupShuffleButton(shuffleModeEnabled)
|
||||
setupPlaybackSettingButton(getPlaybackSetting(repeatMode))
|
||||
maybeUpdatePlaybackSettingButton(getPlaybackSetting(repeatMode))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,10 +426,10 @@ class TrackActivity : SimpleControllerActivity(), PlaybackSpeedListener {
|
|||
}
|
||||
|
||||
private fun updateProgress(currentPosition: Long) {
|
||||
activity_track_progressbar.progress = currentPosition.milliseconds.inWholeSeconds.toInt()
|
||||
binding.activityTrackProgressbar.progress = currentPosition.milliseconds.inWholeSeconds.toInt()
|
||||
}
|
||||
|
||||
private fun updatePlayPause(isPlaying: Boolean) {
|
||||
activity_track_play_pause.updatePlayPauseIcon(isPlaying, getProperTextColor())
|
||||
binding.activityTrackPlayPause.updatePlayPauseIcon(isPlaying, getProperTextColor())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import com.simplemobiletools.musicplayer.adapters.TracksAdapter.Companion.TYPE_F
|
|||
import com.simplemobiletools.musicplayer.adapters.TracksAdapter.Companion.TYPE_PLAYLIST
|
||||
import com.simplemobiletools.musicplayer.adapters.TracksAdapter.Companion.TYPE_TRACKS
|
||||
import com.simplemobiletools.musicplayer.adapters.TracksHeaderAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.ActivityTracksBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.ChangeSortingDialog
|
||||
import com.simplemobiletools.musicplayer.dialogs.ExportPlaylistDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
|
@ -36,8 +37,6 @@ import com.simplemobiletools.musicplayer.extensions.getMediaStoreIdFromPath
|
|||
import com.simplemobiletools.musicplayer.helpers.*
|
||||
import com.simplemobiletools.musicplayer.helpers.M3uExporter.ExportResult
|
||||
import com.simplemobiletools.musicplayer.models.*
|
||||
import kotlinx.android.synthetic.main.activity_tracks.*
|
||||
import kotlinx.android.synthetic.main.view_current_track_bar.current_track_bar
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import java.io.OutputStream
|
||||
|
||||
|
@ -54,31 +53,33 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
private var sourceType = 0
|
||||
private var lastFilePickerPath = ""
|
||||
|
||||
private val binding by viewBinding(ActivityTracksBinding::inflate)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
isMaterialActivity = true
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_tracks)
|
||||
setContentView(binding.root)
|
||||
setupOptionsMenu()
|
||||
refreshMenuItems()
|
||||
|
||||
updateMaterialActivityViews(tracks_coordinator, tracks_holder, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(tracks_list, tracks_toolbar)
|
||||
updateMaterialActivityViews(binding.tracksCoordinator, binding.tracksHolder, useTransparentNavigation = true, useTopSearchMenu = false)
|
||||
setupMaterialScrollListener(binding.tracksList, binding.tracksToolbar)
|
||||
|
||||
val properPrimaryColor = getProperPrimaryColor()
|
||||
tracks_fastscroller.updateColors(properPrimaryColor)
|
||||
tracks_placeholder.setTextColor(getProperTextColor())
|
||||
tracks_placeholder_2.setTextColor(properPrimaryColor)
|
||||
tracks_placeholder_2.underlineText()
|
||||
tracks_placeholder_2.setOnClickListener {
|
||||
binding.tracksFastscroller.updateColors(properPrimaryColor)
|
||||
binding.tracksPlaceholder.setTextColor(getProperTextColor())
|
||||
binding.tracksPlaceholder2.setTextColor(properPrimaryColor)
|
||||
binding.tracksPlaceholder2.underlineText()
|
||||
binding.tracksPlaceholder2.setOnClickListener {
|
||||
addFolderToPlaylist()
|
||||
}
|
||||
|
||||
setupCurrentTrackBar(current_track_bar)
|
||||
setupCurrentTrackBar(binding.currentTrackBar.root)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
setupToolbar(tracks_toolbar, NavigationIcon.Arrow, searchMenuItem = searchMenuItem)
|
||||
setupToolbar(binding.tracksToolbar, NavigationIcon.Arrow, searchMenuItem = searchMenuItem)
|
||||
refreshTracks()
|
||||
}
|
||||
|
||||
|
@ -95,7 +96,7 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
}
|
||||
|
||||
private fun refreshMenuItems() {
|
||||
tracks_toolbar.menu.apply {
|
||||
binding.tracksToolbar.menu.apply {
|
||||
findItem(R.id.search).isVisible = sourceType != TYPE_ALBUM
|
||||
findItem(R.id.sort).isVisible = sourceType != TYPE_ALBUM
|
||||
findItem(R.id.add_file_to_playlist).isVisible = sourceType == TYPE_PLAYLIST
|
||||
|
@ -105,8 +106,8 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
}
|
||||
|
||||
private fun setupOptionsMenu() {
|
||||
setupSearch(tracks_toolbar.menu)
|
||||
tracks_toolbar.setOnMenuItemClickListener { menuItem ->
|
||||
setupSearch(binding.tracksToolbar.menu)
|
||||
binding.tracksToolbar.setOnMenuItemClickListener { menuItem ->
|
||||
when (menuItem.itemId) {
|
||||
R.id.sort -> showSortingDialog()
|
||||
R.id.add_file_to_playlist -> addFileToPlaylist()
|
||||
|
@ -173,11 +174,11 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
folder = intent.getStringExtra(FOLDER)
|
||||
if (folder != null) {
|
||||
sourceType = TYPE_FOLDER
|
||||
tracks_placeholder_2.beGone()
|
||||
binding.tracksPlaceholder2.beGone()
|
||||
}
|
||||
|
||||
val titleToUse = playlist?.title ?: album?.title ?: genre?.title ?: folder ?: ""
|
||||
tracks_toolbar.title = titleToUse
|
||||
binding.tracksToolbar.title = titleToUse
|
||||
refreshMenuItems()
|
||||
|
||||
ensureBackgroundThread {
|
||||
|
@ -187,13 +188,14 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
TYPE_PLAYLIST -> {
|
||||
val playlistTracks = audioHelper.getPlaylistTracks(playlist!!.id)
|
||||
runOnUiThread {
|
||||
tracks_placeholder.beVisibleIf(playlistTracks.isEmpty())
|
||||
tracks_placeholder_2.beVisibleIf(playlistTracks.isEmpty())
|
||||
binding.tracksPlaceholder.beVisibleIf(playlistTracks.isEmpty())
|
||||
binding.tracksPlaceholder2.beVisibleIf(playlistTracks.isEmpty())
|
||||
}
|
||||
|
||||
tracks.addAll(playlistTracks)
|
||||
listItems.addAll(tracks)
|
||||
}
|
||||
|
||||
TYPE_ALBUM -> {
|
||||
val albumTracks = audioHelper.getAlbumTracks(album.id)
|
||||
tracks.addAll(albumTracks)
|
||||
|
@ -202,14 +204,16 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
listItems.add(header)
|
||||
listItems.addAll(tracks)
|
||||
}
|
||||
|
||||
TYPE_TRACKS -> {
|
||||
val genreTracks = audioHelper.getGenreTracks(genre.id)
|
||||
tracks.addAll(genreTracks)
|
||||
}
|
||||
|
||||
else -> {
|
||||
val folderTracks = audioHelper.getFolderTracks(folder.orEmpty())
|
||||
runOnUiThread {
|
||||
tracks_placeholder.beVisibleIf(folderTracks.isEmpty())
|
||||
binding.tracksPlaceholder.beVisibleIf(folderTracks.isEmpty())
|
||||
}
|
||||
|
||||
tracks.addAll(folderTracks)
|
||||
|
@ -219,26 +223,26 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
|
||||
runOnUiThread {
|
||||
if (sourceType == TYPE_ALBUM) {
|
||||
val currAdapter = tracks_list.adapter
|
||||
val currAdapter = binding.tracksList.adapter
|
||||
if (currAdapter == null) {
|
||||
TracksHeaderAdapter(this, listItems, tracks_list) {
|
||||
TracksHeaderAdapter(this, listItems, binding.tracksList) {
|
||||
itemClicked(it as Track)
|
||||
}.apply {
|
||||
tracks_list.adapter = this
|
||||
binding.tracksList.adapter = this
|
||||
}
|
||||
|
||||
if (areSystemAnimationsEnabled) {
|
||||
tracks_list.scheduleLayoutAnimation()
|
||||
binding.tracksList.scheduleLayoutAnimation()
|
||||
}
|
||||
} else {
|
||||
(currAdapter as TracksHeaderAdapter).updateItems(listItems)
|
||||
}
|
||||
} else {
|
||||
val currAdapter = tracks_list.adapter
|
||||
val currAdapter = binding.tracksList.adapter
|
||||
if (currAdapter == null) {
|
||||
TracksAdapter(
|
||||
activity = this,
|
||||
recyclerView = tracks_list,
|
||||
recyclerView = binding.tracksList,
|
||||
sourceType = sourceType,
|
||||
folder = folder,
|
||||
playlist = playlist,
|
||||
|
@ -246,11 +250,11 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
) {
|
||||
itemClicked(it as Track)
|
||||
}.apply {
|
||||
tracks_list.adapter = this
|
||||
binding.tracksList.adapter = this
|
||||
}
|
||||
|
||||
if (areSystemAnimationsEnabled) {
|
||||
tracks_list.scheduleLayoutAnimation()
|
||||
binding.tracksList.scheduleLayoutAnimation()
|
||||
}
|
||||
} else {
|
||||
(currAdapter as TracksAdapter).updateItems(tracks)
|
||||
|
@ -260,9 +264,11 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun getTracksAdapter() = binding.tracksList.adapter as? TracksAdapter
|
||||
|
||||
private fun showSortingDialog() {
|
||||
ChangeSortingDialog(this, ACTIVITY_PLAYLIST_FOLDER, playlist, folder) {
|
||||
val adapter = tracks_list.adapter as? TracksAdapter ?: return@ChangeSortingDialog
|
||||
val adapter = getTracksAdapter() ?: return@ChangeSortingDialog
|
||||
val tracks = adapter.items
|
||||
val sorting = when (sourceType) {
|
||||
TYPE_PLAYLIST -> config.getProperPlaylistSorting(playlist?.id ?: -1)
|
||||
|
@ -286,7 +292,7 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
if (path.isAudioFast()) {
|
||||
addTrackFromPath(path, true)
|
||||
} else {
|
||||
toast(R.string.invalid_file_format)
|
||||
toast(com.simplemobiletools.commons.R.string.invalid_file_format)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +306,7 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
addTrackFromPath(path, false)
|
||||
}
|
||||
} else {
|
||||
toast(R.string.unknown_error_occurred)
|
||||
toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
|
||||
}
|
||||
} else {
|
||||
var track = audioHelper.getTrack(mediaStoreId)
|
||||
|
@ -333,20 +339,20 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
}
|
||||
|
||||
private fun onSearchOpened() {
|
||||
tracksIgnoringSearch = (tracks_list.adapter as? TracksAdapter)?.items ?: return
|
||||
tracksIgnoringSearch = getTracksAdapter()?.items ?: return
|
||||
}
|
||||
|
||||
private fun onSearchClosed() {
|
||||
(tracks_list.adapter as? TracksAdapter)?.updateItems(tracksIgnoringSearch)
|
||||
tracks_placeholder.beGoneIf(tracksIgnoringSearch.isNotEmpty())
|
||||
getTracksAdapter()?.updateItems(tracksIgnoringSearch)
|
||||
binding.tracksPlaceholder.beGoneIf(tracksIgnoringSearch.isNotEmpty())
|
||||
}
|
||||
|
||||
private fun onSearchQueryChanged(text: String) {
|
||||
val filtered = tracksIgnoringSearch.filter {
|
||||
it.title.contains(text, true) || ("${it.artist} - ${it.album}").contains(text, true)
|
||||
}.toMutableList() as ArrayList<Track>
|
||||
(tracks_list.adapter as? TracksAdapter)?.updateItems(filtered, text)
|
||||
tracks_placeholder.beGoneIf(filtered.isNotEmpty())
|
||||
getTracksAdapter()?.updateItems(filtered, text)
|
||||
binding.tracksPlaceholder.beGoneIf(filtered.isNotEmpty())
|
||||
}
|
||||
|
||||
private fun refreshPlaylist() {
|
||||
|
@ -354,16 +360,16 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
|
||||
val newTracks = audioHelper.getPlaylistTracks(playlist!!.id)
|
||||
runOnUiThread {
|
||||
(tracks_list.adapter as? TracksAdapter)?.updateItems(newTracks)
|
||||
tracks_placeholder.beVisibleIf(newTracks.isEmpty())
|
||||
tracks_placeholder_2.beVisibleIf(newTracks.isEmpty())
|
||||
getTracksAdapter()?.updateItems(newTracks)
|
||||
binding.tracksPlaceholder.beVisibleIf(newTracks.isEmpty())
|
||||
binding.tracksPlaceholder2.beVisibleIf(newTracks.isEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
private fun itemClicked(track: Track) {
|
||||
val tracks = when (sourceType) {
|
||||
TYPE_ALBUM -> (tracks_list.adapter as? TracksHeaderAdapter)?.items?.filterIsInstance<Track>()
|
||||
else -> (tracks_list.adapter as? TracksAdapter)?.items
|
||||
TYPE_ALBUM -> (binding.tracksList.adapter as? TracksHeaderAdapter)?.items?.filterIsInstance<Track>()
|
||||
else -> getTracksAdapter()?.items
|
||||
} ?: ArrayList()
|
||||
|
||||
handleNotificationPermission { granted ->
|
||||
|
@ -371,7 +377,7 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
val startIndex = tracks.indexOf(track)
|
||||
prepareAndPlay(tracks, startIndex)
|
||||
} else {
|
||||
PermissionRequiredDialog(this, R.string.allow_notifications_music_player, { openNotificationSettings() })
|
||||
PermissionRequiredDialog(this, com.simplemobiletools.commons.R.string.allow_notifications_music_player, { openNotificationSettings() })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -387,7 +393,7 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
try {
|
||||
startActivityForResult(this, PICK_EXPORT_FILE_INTENT)
|
||||
} catch (e: ActivityNotFoundException) {
|
||||
toast(R.string.system_service_disabled, Toast.LENGTH_LONG)
|
||||
toast(com.simplemobiletools.commons.R.string.system_service_disabled, Toast.LENGTH_LONG)
|
||||
} catch (e: Exception) {
|
||||
showErrorToast(e)
|
||||
}
|
||||
|
@ -407,19 +413,18 @@ class TracksActivity : SimpleMusicActivity() {
|
|||
}
|
||||
|
||||
private fun exportPlaylistTo(outputStream: OutputStream?) {
|
||||
val tracks = (tracks_list.adapter as TracksAdapter).items
|
||||
|
||||
if (tracks.isEmpty()) {
|
||||
toast(R.string.no_entries_for_exporting)
|
||||
val tracks = getTracksAdapter()?.items
|
||||
if (tracks.isNullOrEmpty()) {
|
||||
toast(com.simplemobiletools.commons.R.string.no_entries_for_exporting)
|
||||
return
|
||||
}
|
||||
|
||||
M3uExporter(this).exportPlaylist(outputStream, tracks) { result ->
|
||||
toast(
|
||||
when (result) {
|
||||
ExportResult.EXPORT_OK -> R.string.exporting_successful
|
||||
ExportResult.EXPORT_PARTIAL -> R.string.exporting_some_entries_failed
|
||||
else -> R.string.exporting_failed
|
||||
ExportResult.EXPORT_OK -> com.simplemobiletools.commons.R.string.exporting_successful
|
||||
ExportResult.EXPORT_PARTIAL -> com.simplemobiletools.commons.R.string.exporting_some_entries_failed
|
||||
else -> com.simplemobiletools.commons.R.string.exporting_failed
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
@ -12,16 +12,10 @@ import com.simplemobiletools.commons.dialogs.FeatureLockedDialog
|
|||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.IS_CUSTOMIZING_COLORS
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.WidgetConfigBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.helpers.MyWidgetProvider
|
||||
import com.simplemobiletools.musicplayer.playback.PlaybackService
|
||||
import kotlinx.android.synthetic.main.widget.song_info_artist
|
||||
import kotlinx.android.synthetic.main.widget.song_info_title
|
||||
import kotlinx.android.synthetic.main.widget.view.widget_background
|
||||
import kotlinx.android.synthetic.main.widget_config.*
|
||||
import kotlinx.android.synthetic.main.widget_controls.next_btn
|
||||
import kotlinx.android.synthetic.main.widget_controls.play_pause_btn
|
||||
import kotlinx.android.synthetic.main.widget_controls.previous_btn
|
||||
|
||||
class WidgetConfigureActivity : SimpleActivity() {
|
||||
private var mBgAlpha = 0f
|
||||
|
@ -31,11 +25,13 @@ class WidgetConfigureActivity : SimpleActivity() {
|
|||
private var mBgColorWithoutTransparency = 0
|
||||
private var mFeatureLockedDialog: FeatureLockedDialog? = null
|
||||
|
||||
private val binding by viewBinding(WidgetConfigBinding::inflate)
|
||||
|
||||
public override fun onCreate(savedInstanceState: Bundle?) {
|
||||
useDynamicTheme = false
|
||||
super.onCreate(savedInstanceState)
|
||||
setResult(Activity.RESULT_CANCELED)
|
||||
setContentView(R.layout.widget_config)
|
||||
setContentView(binding.root)
|
||||
initVariables()
|
||||
|
||||
val isCustomizingColors = intent.extras?.getBoolean(IS_CUSTOMIZING_COLORS) ?: false
|
||||
|
@ -45,20 +41,21 @@ class WidgetConfigureActivity : SimpleActivity() {
|
|||
finish()
|
||||
}
|
||||
|
||||
config_save.setOnClickListener { saveConfig() }
|
||||
config_bg_color.setOnClickListener { pickBackgroundColor() }
|
||||
config_text_color.setOnClickListener { pickTextColor() }
|
||||
binding.configSave.setOnClickListener { saveConfig() }
|
||||
binding.configBgColor.setOnClickListener { pickBackgroundColor() }
|
||||
binding.configTextColor.setOnClickListener { pickTextColor() }
|
||||
|
||||
val primaryColor = getProperPrimaryColor()
|
||||
config_bg_seekbar.setColors(mTextColor, primaryColor, primaryColor)
|
||||
|
||||
val currSong = PlaybackService.currentMediaItem?.mediaMetadata
|
||||
if (currSong != null) {
|
||||
song_info_title.text = currSong.title
|
||||
song_info_artist.text = currSong.artist
|
||||
} else {
|
||||
song_info_title.text = getString(R.string.artist)
|
||||
song_info_artist.text = getString(R.string.song_title)
|
||||
binding.configBgSeekbar.setColors(mTextColor, primaryColor, primaryColor)
|
||||
binding.configPlayer.apply {
|
||||
val currSong = PlaybackService.currentMediaItem?.mediaMetadata
|
||||
if (currSong != null) {
|
||||
songInfoTitle.text = currSong.title
|
||||
songInfoArtist.text = currSong.artist
|
||||
} else {
|
||||
songInfoTitle.text = getString(com.simplemobiletools.commons.R.string.artist)
|
||||
songInfoArtist.text = getString(com.simplemobiletools.commons.R.string.song_title)
|
||||
}
|
||||
}
|
||||
|
||||
if (!isCustomizingColors && !isOrWasThankYouInstalled()) {
|
||||
|
@ -82,16 +79,16 @@ class WidgetConfigureActivity : SimpleActivity() {
|
|||
mBgAlpha = Color.alpha(mBgColor) / 255.toFloat()
|
||||
|
||||
mBgColorWithoutTransparency = Color.rgb(Color.red(mBgColor), Color.green(mBgColor), Color.blue(mBgColor))
|
||||
config_bg_seekbar.progress = (mBgAlpha * 100).toInt()
|
||||
binding.configBgSeekbar.progress = (mBgAlpha * 100).toInt()
|
||||
updateBackgroundColor()
|
||||
config_bg_seekbar.onSeekBarChangeListener { progress ->
|
||||
binding.configBgSeekbar.onSeekBarChangeListener { progress ->
|
||||
mBgAlpha = progress / 100.toFloat()
|
||||
updateBackgroundColor()
|
||||
}
|
||||
|
||||
mTextColor = config.widgetTextColor
|
||||
if (mTextColor == resources.getColor(R.color.default_widget_text_color) && config.isUsingSystemTheme) {
|
||||
mTextColor = resources.getColor(R.color.you_primary_color, theme)
|
||||
if (mTextColor == resources.getColor(com.simplemobiletools.commons.R.color.default_widget_text_color) && config.isUsingSystemTheme) {
|
||||
mTextColor = resources.getColor(com.simplemobiletools.commons.R.color.you_primary_color, theme)
|
||||
}
|
||||
|
||||
updateTextColor()
|
||||
|
@ -133,23 +130,23 @@ class WidgetConfigureActivity : SimpleActivity() {
|
|||
}
|
||||
}
|
||||
|
||||
private fun updateBackgroundColor() {
|
||||
private fun updateBackgroundColor() = binding.apply {
|
||||
mBgColor = mBgColorWithoutTransparency.adjustAlpha(mBgAlpha)
|
||||
config_player.widget_background.applyColorFilter(mBgColor)
|
||||
config_bg_color.setFillWithStroke(mBgColor, mBgColor)
|
||||
config_save.backgroundTintList = ColorStateList.valueOf(getProperPrimaryColor())
|
||||
configPlayer.widgetBackground.applyColorFilter(mBgColor)
|
||||
configBgColor.setFillWithStroke(mBgColor, mBgColor)
|
||||
configSave.backgroundTintList = ColorStateList.valueOf(getProperPrimaryColor())
|
||||
}
|
||||
|
||||
private fun updateTextColor() {
|
||||
config_text_color.setFillWithStroke(mTextColor, mTextColor)
|
||||
private fun updateTextColor() = binding.apply {
|
||||
configTextColor.setFillWithStroke(mTextColor, mTextColor)
|
||||
|
||||
song_info_title.setTextColor(mTextColor)
|
||||
song_info_artist.setTextColor(mTextColor)
|
||||
config_save.setTextColor(getProperPrimaryColor().getContrastColor())
|
||||
configPlayer.songInfoTitle.setTextColor(mTextColor)
|
||||
configPlayer.songInfoArtist.setTextColor(mTextColor)
|
||||
configSave.setTextColor(getProperPrimaryColor().getContrastColor())
|
||||
|
||||
previous_btn.drawable.applyColorFilter(mTextColor)
|
||||
play_pause_btn.drawable.applyColorFilter(mTextColor)
|
||||
next_btn.drawable.applyColorFilter(mTextColor)
|
||||
configPlayer.widgetControls.previousBtn.drawable.applyColorFilter(mTextColor)
|
||||
configPlayer.widgetControls.playPauseBtn.drawable.applyColorFilter(mTextColor)
|
||||
configPlayer.widgetControls.nextBtn.drawable.applyColorFilter(mTextColor)
|
||||
}
|
||||
|
||||
private fun pickBackgroundColor() {
|
||||
|
|
|
@ -10,20 +10,23 @@ import com.simplemobiletools.commons.extensions.setupViewBackground
|
|||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemAlbumBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.extensions.getAlbumCoverArt
|
||||
import com.simplemobiletools.musicplayer.inlines.indexOfFirstOrNull
|
||||
import com.simplemobiletools.musicplayer.models.Album
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import kotlinx.android.synthetic.main.item_album.view.album_frame
|
||||
import kotlinx.android.synthetic.main.item_album.view.album_title
|
||||
import kotlinx.android.synthetic.main.item_album.view.album_tracks
|
||||
|
||||
class AlbumsAdapter(activity: BaseSimpleActivity, items: ArrayList<Album>, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) :
|
||||
BaseMusicAdapter<Album>(items, activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
|
||||
override fun getActionMenuId() = R.menu.cab_albums
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_album, parent)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = ItemAlbumBinding.inflate(layoutInflater, parent, false)
|
||||
return createViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val album = items.getOrNull(position) ?: return
|
||||
|
@ -48,19 +51,19 @@ class AlbumsAdapter(activity: BaseSimpleActivity, items: ArrayList<Album>, recyc
|
|||
}
|
||||
|
||||
override fun getSelectedTracks(): List<Track> {
|
||||
return ctx.audioHelper.getAlbumTracks(getSelectedItems())
|
||||
return context.audioHelper.getAlbumTracks(getSelectedItems())
|
||||
}
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
ConfirmationDialog(ctx) {
|
||||
ConfirmationDialog(context) {
|
||||
ensureBackgroundThread {
|
||||
val selectedAlbums = getSelectedItems()
|
||||
val positions = selectedAlbums.mapNotNull { album -> items.indexOfFirstOrNull { it.id == album.id } } as ArrayList<Int>
|
||||
val tracks = ctx.audioHelper.getAlbumTracks(selectedAlbums)
|
||||
ctx.audioHelper.deleteAlbums(selectedAlbums)
|
||||
val tracks = context.audioHelper.getAlbumTracks(selectedAlbums)
|
||||
context.audioHelper.deleteAlbums(selectedAlbums)
|
||||
|
||||
ctx.deleteTracks(tracks) {
|
||||
ctx.runOnUiThread {
|
||||
context.deleteTracks(tracks) {
|
||||
context.runOnUiThread {
|
||||
positions.sortDescending()
|
||||
removeSelectedItems(positions)
|
||||
positions.forEach {
|
||||
|
@ -75,21 +78,21 @@ class AlbumsAdapter(activity: BaseSimpleActivity, items: ArrayList<Album>, recyc
|
|||
}
|
||||
|
||||
private fun setupView(view: View, album: Album) {
|
||||
view.apply {
|
||||
setupViewBackground(ctx)
|
||||
album_frame?.isSelected = selectedKeys.contains(album.hashCode())
|
||||
album_title.text = if (textToHighlight.isEmpty()) album.title else album.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
album_title.setTextColor(textColor)
|
||||
ItemAlbumBinding.bind(view).apply {
|
||||
root.setupViewBackground(context)
|
||||
albumFrame.isSelected = selectedKeys.contains(album.hashCode())
|
||||
albumTitle.text = if (textToHighlight.isEmpty()) album.title else album.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
albumTitle.setTextColor(textColor)
|
||||
|
||||
val tracks = resources.getQuantityString(R.plurals.tracks_plural, album.trackCnt, album.trackCnt)
|
||||
album_tracks.text = tracks
|
||||
album_tracks.setTextColor(textColor)
|
||||
albumTracks.text = tracks
|
||||
albumTracks.setTextColor(textColor)
|
||||
|
||||
ctx.getAlbumCoverArt(album) { coverArt ->
|
||||
loadImage(findViewById(R.id.album_image), coverArt, placeholderBig)
|
||||
context.getAlbumCoverArt(album) { coverArt ->
|
||||
loadImage(albumImage, coverArt, placeholderBig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(ctx.config.albumSorting) ?: ""
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(context.config.albumSorting) ?: ""
|
||||
}
|
||||
|
|
|
@ -13,6 +13,9 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
|||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemAlbumBinding
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemSectionBinding
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemTrackBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.EditDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.getAlbumCoverArt
|
||||
|
@ -22,11 +25,6 @@ import com.simplemobiletools.musicplayer.models.Album
|
|||
import com.simplemobiletools.musicplayer.models.AlbumSection
|
||||
import com.simplemobiletools.musicplayer.models.ListItem
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import kotlinx.android.synthetic.main.item_album.view.album_frame
|
||||
import kotlinx.android.synthetic.main.item_album.view.album_title
|
||||
import kotlinx.android.synthetic.main.item_album.view.album_tracks
|
||||
import kotlinx.android.synthetic.main.item_section.view.item_section
|
||||
import kotlinx.android.synthetic.main.item_track.view.*
|
||||
|
||||
// we show both albums and individual tracks here
|
||||
class AlbumsTracksAdapter(
|
||||
|
@ -41,13 +39,13 @@ class AlbumsTracksAdapter(
|
|||
override fun getActionMenuId() = R.menu.cab_albums_tracks
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val layout = when (viewType) {
|
||||
ITEM_SECTION -> R.layout.item_section
|
||||
ITEM_ALBUM -> R.layout.item_album
|
||||
else -> R.layout.item_track
|
||||
val binding = when (viewType) {
|
||||
ITEM_SECTION -> ItemSectionBinding.inflate(layoutInflater, parent, false)
|
||||
ITEM_ALBUM -> ItemAlbumBinding.inflate(layoutInflater, parent, false)
|
||||
else -> ItemTrackBinding.inflate(layoutInflater, parent, false)
|
||||
}
|
||||
|
||||
return createViewHolder(layout, parent)
|
||||
return createViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
|
@ -99,7 +97,7 @@ class AlbumsTracksAdapter(
|
|||
override fun getIsItemSelectable(position: Int) = items[position] !is AlbumSection
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
ConfirmationDialog(ctx) {
|
||||
ConfirmationDialog(context) {
|
||||
ensureBackgroundThread {
|
||||
val positions = ArrayList<Int>()
|
||||
val selectedTracks = getAllSelectedTracks()
|
||||
|
@ -108,8 +106,8 @@ class AlbumsTracksAdapter(
|
|||
positions += selectedTracks.mapNotNull { track -> items.indexOfFirstOrNull { it is Track && it.mediaStoreId == track.mediaStoreId } }
|
||||
positions += selectedAlbums.mapNotNull { album -> items.indexOfFirstOrNull { it is Album && it.id == album.id } }
|
||||
|
||||
ctx.deleteTracks(selectedTracks) {
|
||||
ctx.runOnUiThread {
|
||||
context.deleteTracks(selectedTracks) {
|
||||
context.runOnUiThread {
|
||||
positions.sortDescending()
|
||||
removeSelectedItems(positions)
|
||||
positions.forEach {
|
||||
|
@ -118,7 +116,7 @@ class AlbumsTracksAdapter(
|
|||
|
||||
// finish activity if all tracks are deleted
|
||||
if (items.none { it is Track }) {
|
||||
ctx.finish()
|
||||
context.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,50 +126,51 @@ class AlbumsTracksAdapter(
|
|||
|
||||
override fun getAllSelectedTracks(): List<Track> {
|
||||
val tracks = getSelectedTracks().toMutableList()
|
||||
tracks.addAll(ctx.audioHelper.getAlbumTracks(getSelectedAlbums()))
|
||||
tracks.addAll(context.audioHelper.getAlbumTracks(getSelectedAlbums()))
|
||||
return tracks
|
||||
}
|
||||
|
||||
private fun getSelectedAlbums(): List<Album> = getSelectedItems().filterIsInstance<Album>().toList()
|
||||
|
||||
private fun setupAlbum(view: View, album: Album) {
|
||||
view.apply {
|
||||
album_frame?.isSelected = selectedKeys.contains(album.hashCode())
|
||||
album_title.text = album.title
|
||||
album_title.setTextColor(textColor)
|
||||
album_tracks.text = resources.getQuantityString(R.plurals.tracks_plural, album.trackCnt, album.trackCnt)
|
||||
album_tracks.setTextColor(textColor)
|
||||
ItemAlbumBinding.bind(view).apply {
|
||||
root.setupViewBackground(context)
|
||||
albumFrame.isSelected = selectedKeys.contains(album.hashCode())
|
||||
albumTitle.text = album.title
|
||||
albumTitle.setTextColor(textColor)
|
||||
albumTracks.text = resources.getQuantityString(R.plurals.tracks_plural, album.trackCnt, album.trackCnt)
|
||||
albumTracks.setTextColor(textColor)
|
||||
|
||||
ctx.getAlbumCoverArt(album) { coverArt ->
|
||||
loadImage(findViewById(R.id.album_image), coverArt, placeholderBig)
|
||||
context.getAlbumCoverArt(album) { coverArt ->
|
||||
loadImage(albumImage, coverArt, placeholderBig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupTrack(view: View, track: Track) {
|
||||
view.apply {
|
||||
setupViewBackground(ctx)
|
||||
track_frame?.isSelected = selectedKeys.contains(track.hashCode())
|
||||
track_title.text = track.title
|
||||
track_title.setTextColor(textColor)
|
||||
track_info.text = track.album
|
||||
track_info.setTextColor(textColor)
|
||||
ItemTrackBinding.bind(view).apply {
|
||||
root.setupViewBackground(context)
|
||||
trackFrame.isSelected = selectedKeys.contains(track.hashCode())
|
||||
trackTitle.text = track.title
|
||||
trackTitle.setTextColor(textColor)
|
||||
trackInfo.text = track.album
|
||||
trackInfo.setTextColor(textColor)
|
||||
|
||||
track_id.beGone()
|
||||
track_image.beVisible()
|
||||
track_duration.text = track.duration.getFormattedDuration()
|
||||
track_duration.setTextColor(textColor)
|
||||
trackId.beGone()
|
||||
trackImage.beVisible()
|
||||
trackDuration.text = track.duration.getFormattedDuration()
|
||||
trackDuration.setTextColor(textColor)
|
||||
|
||||
ctx.getTrackCoverArt(track) { coverArt ->
|
||||
loadImage(findViewById(R.id.track_image), coverArt, placeholder)
|
||||
context.getTrackCoverArt(track) { coverArt ->
|
||||
loadImage(trackImage, coverArt, placeholder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupSection(view: View, section: AlbumSection) {
|
||||
view.apply {
|
||||
item_section.text = section.title
|
||||
item_section.setTextColor(textColor)
|
||||
ItemSectionBinding.bind(view).apply {
|
||||
itemSection.text = section.title
|
||||
itemSection.setTextColor(textColor)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,7 +185,7 @@ class AlbumsTracksAdapter(
|
|||
|
||||
private fun displayEditDialog() {
|
||||
getSelectedTracks().firstOrNull()?.let { selectedTrack ->
|
||||
EditDialog(ctx as SimpleActivity, selectedTrack) { track ->
|
||||
EditDialog(context as SimpleActivity, selectedTrack) { track ->
|
||||
val trackIndex = items.indexOfFirst { (it as? Track)?.mediaStoreId == track.mediaStoreId }
|
||||
if (trackIndex != -1) {
|
||||
items[trackIndex] = track
|
||||
|
@ -194,7 +193,7 @@ class AlbumsTracksAdapter(
|
|||
finishActMode()
|
||||
}
|
||||
|
||||
ctx.refreshQueueAndTracks(track)
|
||||
context.refreshQueueAndTracks(track)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,20 +11,21 @@ import com.simplemobiletools.commons.extensions.setupViewBackground
|
|||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemArtistBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.inlines.indexOfFirstOrNull
|
||||
import com.simplemobiletools.musicplayer.models.Artist
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import kotlinx.android.synthetic.main.item_artist.view.artist_albums_tracks
|
||||
import kotlinx.android.synthetic.main.item_artist.view.artist_frame
|
||||
import kotlinx.android.synthetic.main.item_artist.view.artist_title
|
||||
|
||||
class ArtistsAdapter(activity: BaseSimpleActivity, items: ArrayList<Artist>, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) :
|
||||
BaseMusicAdapter<Artist>(items, activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
|
||||
override fun getActionMenuId() = R.menu.cab_artists
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_artist, parent)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = ItemArtistBinding.inflate(layoutInflater, parent, false)
|
||||
return createViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val artist = items.getOrNull(position) ?: return
|
||||
|
@ -49,20 +50,20 @@ class ArtistsAdapter(activity: BaseSimpleActivity, items: ArrayList<Artist>, rec
|
|||
}
|
||||
|
||||
override fun getSelectedTracks(): ArrayList<Track> {
|
||||
val albums = ctx.audioHelper.getArtistAlbums(getSelectedItems())
|
||||
return ctx.audioHelper.getAlbumTracks(albums)
|
||||
val albums = context.audioHelper.getArtistAlbums(getSelectedItems())
|
||||
return context.audioHelper.getAlbumTracks(albums)
|
||||
}
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
ConfirmationDialog(ctx) {
|
||||
ConfirmationDialog(context) {
|
||||
ensureBackgroundThread {
|
||||
val selectedArtists = getSelectedItems()
|
||||
val positions = selectedArtists.mapNotNull { artist -> items.indexOfFirstOrNull { it.id == artist.id } } as ArrayList<Int>
|
||||
val tracks = ctx.audioHelper.getArtistTracks(selectedArtists)
|
||||
val tracks = context.audioHelper.getArtistTracks(selectedArtists)
|
||||
|
||||
ctx.audioHelper.deleteArtists(selectedArtists)
|
||||
ctx.deleteTracks(tracks) {
|
||||
ctx.runOnUiThread {
|
||||
context.audioHelper.deleteArtists(selectedArtists)
|
||||
context.deleteTracks(tracks) {
|
||||
context.runOnUiThread {
|
||||
positions.sortDescending()
|
||||
removeSelectedItems(positions)
|
||||
positions.forEach {
|
||||
|
@ -77,23 +78,23 @@ class ArtistsAdapter(activity: BaseSimpleActivity, items: ArrayList<Artist>, rec
|
|||
}
|
||||
|
||||
private fun setupView(view: View, artist: Artist) {
|
||||
view.apply {
|
||||
setupViewBackground(ctx)
|
||||
artist_frame?.isSelected = selectedKeys.contains(artist.hashCode())
|
||||
artist_title.text = if (textToHighlight.isEmpty()) artist.title else artist.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
artist_title.setTextColor(textColor)
|
||||
ItemArtistBinding.bind(view).apply {
|
||||
root.setupViewBackground(context)
|
||||
artistFrame.isSelected = selectedKeys.contains(artist.hashCode())
|
||||
artistTitle.text = if (textToHighlight.isEmpty()) artist.title else artist.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
artistTitle.setTextColor(textColor)
|
||||
|
||||
val albums = resources.getQuantityString(R.plurals.albums_plural, artist.albumCnt, artist.albumCnt)
|
||||
val tracks = resources.getQuantityString(R.plurals.tracks_plural, artist.trackCnt, artist.trackCnt)
|
||||
@SuppressLint("SetTextI18n")
|
||||
artist_albums_tracks.text = "$albums, $tracks"
|
||||
artist_albums_tracks.setTextColor(textColor)
|
||||
artistAlbumsTracks.text = "$albums, $tracks"
|
||||
artistAlbumsTracks.setTextColor(textColor)
|
||||
|
||||
ctx.getArtistCoverArt(artist) { coverArt ->
|
||||
loadImage(findViewById(R.id.artist_image), coverArt, placeholder)
|
||||
context.getArtistCoverArt(artist) { coverArt ->
|
||||
loadImage(artistImage, coverArt, placeholder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(ctx.config.artistSorting) ?: ""
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(context.config.artistSorting) ?: ""
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simplemobiletools.musicplayer.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.Menu
|
||||
import android.widget.ImageView
|
||||
|
@ -9,9 +10,9 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
|||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||
import com.simplemobiletools.commons.extensions.getProperPrimaryColor
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.activities.SimpleControllerActivity
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.helpers.TagHelper
|
||||
|
@ -25,13 +26,17 @@ abstract class BaseMusicAdapter<Type>(
|
|||
itemClick: (Any) -> Unit
|
||||
) : MyRecyclerViewAdapter(activity, recyclerView, itemClick) {
|
||||
|
||||
val ctx = activity as SimpleControllerActivity
|
||||
val context = activity as SimpleControllerActivity
|
||||
|
||||
var textToHighlight = ""
|
||||
val tagHelper by lazy { TagHelper(ctx) }
|
||||
val placeholder by lazy { resources.getSmallPlaceholder(textColor) }
|
||||
val placeholderBig by lazy { resources.getBiggerPlaceholder(textColor) }
|
||||
open val cornerRadius by lazy { resources.getDimension(R.dimen.rounded_corner_radius_small).toInt() }
|
||||
val tagHelper by lazy { TagHelper(context) }
|
||||
var placeholder = resources.getSmallPlaceholder(textColor)
|
||||
var placeholderBig = resources.getBiggerPlaceholder(textColor)
|
||||
open val cornerRadius by lazy { resources.getDimension(com.simplemobiletools.commons.R.dimen.rounded_corner_radius_small).toInt() }
|
||||
|
||||
init {
|
||||
setupDragListener(true)
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
|
@ -91,8 +96,8 @@ abstract class BaseMusicAdapter<Type>(
|
|||
fun addToQueue() {
|
||||
ensureBackgroundThread {
|
||||
val allSelectedTracks = getAllSelectedTracks()
|
||||
ctx.runOnUiThread {
|
||||
ctx.addTracksToQueue(allSelectedTracks) {
|
||||
context.runOnUiThread {
|
||||
context.addTracksToQueue(allSelectedTracks) {
|
||||
finishActMode()
|
||||
}
|
||||
}
|
||||
|
@ -102,8 +107,8 @@ abstract class BaseMusicAdapter<Type>(
|
|||
fun playNextInQueue() {
|
||||
ensureBackgroundThread {
|
||||
getSelectedTracks().firstOrNull()?.let { selectedTrack ->
|
||||
ctx.runOnUiThread {
|
||||
ctx.playNextInQueue(selectedTrack) {
|
||||
context.runOnUiThread {
|
||||
context.playNextInQueue(selectedTrack) {
|
||||
finishActMode()
|
||||
}
|
||||
}
|
||||
|
@ -114,8 +119,8 @@ abstract class BaseMusicAdapter<Type>(
|
|||
fun addToPlaylist() {
|
||||
ensureBackgroundThread {
|
||||
val allSelectedTracks = getAllSelectedTracks()
|
||||
ctx.runOnUiThread {
|
||||
ctx.addTracksToPlaylist(allSelectedTracks) {
|
||||
context.runOnUiThread {
|
||||
context.addTracksToPlaylist(allSelectedTracks) {
|
||||
finishActMode()
|
||||
notifyDataChanged()
|
||||
}
|
||||
|
@ -125,7 +130,7 @@ abstract class BaseMusicAdapter<Type>(
|
|||
|
||||
fun shareFiles() {
|
||||
ensureBackgroundThread {
|
||||
ctx.shareFiles(getAllSelectedTracks())
|
||||
context.shareFiles(getAllSelectedTracks())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,8 +141,8 @@ abstract class BaseMusicAdapter<Type>(
|
|||
return@ensureBackgroundThread
|
||||
}
|
||||
|
||||
ctx.runOnUiThread {
|
||||
ctx.showTrackProperties(selectedTracks)
|
||||
context.runOnUiThread {
|
||||
context.showTrackProperties(selectedTracks)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -147,13 +152,28 @@ abstract class BaseMusicAdapter<Type>(
|
|||
.error(placeholder)
|
||||
.transform(CenterCrop(), RoundedCorners(cornerRadius))
|
||||
|
||||
ctx.ensureActivityNotDestroyed {
|
||||
Glide.with(ctx)
|
||||
context.ensureActivityNotDestroyed {
|
||||
Glide.with(context)
|
||||
.load(resource)
|
||||
.apply(options)
|
||||
.into(imageView)
|
||||
}
|
||||
}
|
||||
|
||||
fun notifyDataChanged() = notifyItemRangeChanged(0, itemCount)
|
||||
fun updateColors(newTextColor: Int) {
|
||||
if (textColor != newTextColor || properPrimaryColor != context.getProperPrimaryColor()) {
|
||||
updateTextColor(newTextColor)
|
||||
updatePrimaryColor()
|
||||
placeholder = resources.getSmallPlaceholder(textColor)
|
||||
placeholderBig = resources.getBiggerPlaceholder(textColor)
|
||||
notifyDataChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
fun notifyDataChanged() = if (itemCount == 0) {
|
||||
notifyDataSetChanged()
|
||||
} else {
|
||||
notifyItemRangeChanged(0, itemCount)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simplemobiletools.musicplayer.adapters
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.*
|
||||
import android.widget.PopupMenu
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
|
@ -10,9 +11,8 @@ import com.simplemobiletools.commons.extensions.humanizePath
|
|||
import com.simplemobiletools.commons.extensions.setupViewBackground
|
||||
import com.simplemobiletools.commons.interfaces.RefreshRecyclerViewListener
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemExcludedFolderBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import kotlinx.android.synthetic.main.item_excluded_folder.view.*
|
||||
|
||||
class ExcludedFoldersAdapter(
|
||||
activity: BaseSimpleActivity,
|
||||
|
@ -24,13 +24,17 @@ class ExcludedFoldersAdapter(
|
|||
|
||||
private val config = activity.config
|
||||
|
||||
override fun getActionMenuId() = R.menu.cab_remove_only
|
||||
init {
|
||||
setupDragListener(true)
|
||||
}
|
||||
|
||||
override fun getActionMenuId() = com.simplemobiletools.commons.R.menu.cab_remove_only
|
||||
|
||||
override fun prepareActionMode(menu: Menu) {}
|
||||
|
||||
override fun actionItemPressed(id: Int) {
|
||||
when (id) {
|
||||
R.id.cab_remove -> removeSelection()
|
||||
com.simplemobiletools.commons.R.id.cab_remove -> removeSelection()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,11 +50,14 @@ class ExcludedFoldersAdapter(
|
|||
|
||||
override fun onActionModeDestroyed() {}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_excluded_folder, parent)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = ItemExcludedFolderBinding.inflate(layoutInflater, parent, false)
|
||||
return createViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val folder = folders[position]
|
||||
holder.bindView(folder, true, true) { itemView, adapterPosition ->
|
||||
holder.bindView(folder, allowSingleClick = true, allowLongClick = true) { itemView, _ ->
|
||||
setupView(itemView, folder)
|
||||
}
|
||||
bindViewHolder(holder)
|
||||
|
@ -61,21 +68,22 @@ class ExcludedFoldersAdapter(
|
|||
private fun getSelectedItems() = folders.filter { selectedKeys.contains(it.hashCode()) } as ArrayList<String>
|
||||
|
||||
private fun setupView(view: View, folder: String) {
|
||||
view.apply {
|
||||
setupViewBackground(activity)
|
||||
excluded_folder_holder?.isSelected = selectedKeys.contains(folder.hashCode())
|
||||
excluded_folder_title.apply {
|
||||
ItemExcludedFolderBinding.bind(view).apply {
|
||||
root.setupViewBackground(activity)
|
||||
excludedFolderHolder.isSelected = selectedKeys.contains(folder.hashCode())
|
||||
excludedFolderTitle.apply {
|
||||
@SuppressLint("SetTextI18n")
|
||||
text = context.humanizePath(folder) + "/"
|
||||
setTextColor(context.getProperTextColor())
|
||||
}
|
||||
|
||||
overflow_menu_icon.drawable.apply {
|
||||
overflowMenuIcon.drawable.apply {
|
||||
mutate()
|
||||
setTint(activity.getProperTextColor())
|
||||
}
|
||||
|
||||
overflow_menu_icon.setOnClickListener {
|
||||
showPopupMenu(overflow_menu_anchor, folder)
|
||||
overflowMenuIcon.setOnClickListener {
|
||||
showPopupMenu(overflowMenuAnchor, folder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +98,7 @@ class ExcludedFoldersAdapter(
|
|||
setOnMenuItemClickListener { item ->
|
||||
val eventTypeId = folder.hashCode()
|
||||
when (item.itemId) {
|
||||
R.id.cab_remove -> {
|
||||
com.simplemobiletools.commons.R.id.cab_remove -> {
|
||||
executeItemMenuOperation(eventTypeId) {
|
||||
removeSelection()
|
||||
}
|
||||
|
|
|
@ -8,14 +8,12 @@ import com.simplemobiletools.commons.extensions.highlightTextPart
|
|||
import com.simplemobiletools.commons.extensions.setupViewBackground
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemFolderBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.models.Events
|
||||
import com.simplemobiletools.musicplayer.models.Folder
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import kotlinx.android.synthetic.main.item_folder.view.folder_frame
|
||||
import kotlinx.android.synthetic.main.item_folder.view.folder_title
|
||||
import kotlinx.android.synthetic.main.item_folder.view.folder_tracks
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
class FoldersAdapter(
|
||||
|
@ -24,7 +22,10 @@ class FoldersAdapter(
|
|||
|
||||
override fun getActionMenuId() = R.menu.cab_folders
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_folder, parent)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = ItemFolderBinding.inflate(layoutInflater, parent, false)
|
||||
return createViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val folder = items.getOrNull(position) ?: return
|
||||
|
@ -43,7 +44,7 @@ class FoldersAdapter(
|
|||
|
||||
private fun excludeFolders() {
|
||||
getSelectedItems().forEach {
|
||||
ctx.config.addExcludedFolder(it.path)
|
||||
context.config.addExcludedFolder(it.path)
|
||||
}
|
||||
|
||||
finishActMode()
|
||||
|
@ -53,24 +54,24 @@ class FoldersAdapter(
|
|||
override fun getSelectedTracks(): List<Track> {
|
||||
val tracks = arrayListOf<Track>()
|
||||
getSelectedItems().forEach {
|
||||
tracks += ctx.audioHelper.getFolderTracks(it.title)
|
||||
tracks += context.audioHelper.getFolderTracks(it.title)
|
||||
}
|
||||
|
||||
return tracks
|
||||
}
|
||||
|
||||
private fun setupView(view: View, folder: Folder) {
|
||||
view.apply {
|
||||
setupViewBackground(ctx)
|
||||
folder_frame?.isSelected = selectedKeys.contains(folder.hashCode())
|
||||
folder_title.text = if (textToHighlight.isEmpty()) folder.title else folder.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
folder_title.setTextColor(textColor)
|
||||
ItemFolderBinding.bind(view).apply {
|
||||
root.setupViewBackground(context)
|
||||
folderFrame.isSelected = selectedKeys.contains(folder.hashCode())
|
||||
folderTitle.text = if (textToHighlight.isEmpty()) folder.title else folder.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
folderTitle.setTextColor(textColor)
|
||||
|
||||
val tracks = resources.getQuantityString(R.plurals.tracks_plural, folder.trackCount, folder.trackCount)
|
||||
folder_tracks.text = tracks
|
||||
folder_tracks.setTextColor(textColor)
|
||||
folderTracks.text = tracks
|
||||
folderTracks.setTextColor(textColor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(ctx.config.folderSorting) ?: ""
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(context.config.folderSorting) ?: ""
|
||||
}
|
||||
|
|
|
@ -10,20 +10,23 @@ import com.simplemobiletools.commons.extensions.setupViewBackground
|
|||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemGenreBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.extensions.getGenreCoverArt
|
||||
import com.simplemobiletools.musicplayer.inlines.indexOfFirstOrNull
|
||||
import com.simplemobiletools.musicplayer.models.Genre
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import kotlinx.android.synthetic.main.item_genre.view.genre_frame
|
||||
import kotlinx.android.synthetic.main.item_genre.view.genre_title
|
||||
import kotlinx.android.synthetic.main.item_genre.view.genre_tracks
|
||||
|
||||
class GenresAdapter(activity: BaseSimpleActivity, items: ArrayList<Genre>, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) :
|
||||
BaseMusicAdapter<Genre>(items, activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
|
||||
override fun getActionMenuId() = R.menu.cab_genres
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_genre, parent)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = ItemGenreBinding.inflate(layoutInflater, parent, false)
|
||||
return createViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val genre = items.getOrNull(position) ?: return
|
||||
|
@ -48,19 +51,19 @@ class GenresAdapter(activity: BaseSimpleActivity, items: ArrayList<Genre>, recyc
|
|||
}
|
||||
|
||||
override fun getSelectedTracks(): ArrayList<Track> {
|
||||
return ctx.audioHelper.getGenreTracks(getSelectedItems())
|
||||
return context.audioHelper.getGenreTracks(getSelectedItems())
|
||||
}
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
ConfirmationDialog(ctx) {
|
||||
ConfirmationDialog(context) {
|
||||
ensureBackgroundThread {
|
||||
val selectedGenres = getSelectedItems()
|
||||
val positions = selectedGenres.mapNotNull { genre -> items.indexOfFirstOrNull { it.id == genre.id } } as ArrayList<Int>
|
||||
val tracks = ctx.audioHelper.getGenreTracks(selectedGenres)
|
||||
ctx.audioHelper.deleteGenres(selectedGenres)
|
||||
val tracks = context.audioHelper.getGenreTracks(selectedGenres)
|
||||
context.audioHelper.deleteGenres(selectedGenres)
|
||||
|
||||
ctx.deleteTracks(tracks) {
|
||||
ctx.runOnUiThread {
|
||||
context.deleteTracks(tracks) {
|
||||
context.runOnUiThread {
|
||||
positions.sortDescending()
|
||||
removeSelectedItems(positions)
|
||||
positions.forEach {
|
||||
|
@ -75,26 +78,26 @@ class GenresAdapter(activity: BaseSimpleActivity, items: ArrayList<Genre>, recyc
|
|||
}
|
||||
|
||||
private fun setupView(view: View, genre: Genre) {
|
||||
view.apply {
|
||||
setupViewBackground(context)
|
||||
genre_frame?.isSelected = selectedKeys.contains(genre.hashCode())
|
||||
genre_title.text = if (textToHighlight.isEmpty()) {
|
||||
ItemGenreBinding.bind(view).apply {
|
||||
root.setupViewBackground(activity)
|
||||
genreFrame.isSelected = selectedKeys.contains(genre.hashCode())
|
||||
genreTitle.text = if (textToHighlight.isEmpty()) {
|
||||
genre.title
|
||||
} else {
|
||||
genre.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
}
|
||||
|
||||
genre_title.setTextColor(textColor)
|
||||
genreTitle.setTextColor(textColor)
|
||||
|
||||
val tracks = resources.getQuantityString(R.plurals.tracks_plural, genre.trackCnt, genre.trackCnt)
|
||||
genre_tracks.text = tracks
|
||||
genre_tracks.setTextColor(textColor)
|
||||
genreTracks.text = tracks
|
||||
genreTracks.setTextColor(textColor)
|
||||
|
||||
context.getGenreCoverArt(genre) { coverArt ->
|
||||
loadImage(findViewById(R.id.genre_image), coverArt, placeholderBig)
|
||||
activity.getGenreCoverArt(genre) { coverArt ->
|
||||
loadImage(genreImage, coverArt, placeholderBig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(ctx.config.genreSorting) ?: ""
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(context.config.genreSorting) ?: ""
|
||||
}
|
||||
|
|
|
@ -13,15 +13,13 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
|||
import com.simplemobiletools.commons.models.FileDirItem
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemPlaylistBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.NewPlaylistDialog
|
||||
import com.simplemobiletools.musicplayer.dialogs.RemovePlaylistDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.models.Events
|
||||
import com.simplemobiletools.musicplayer.models.Playlist
|
||||
import kotlinx.android.synthetic.main.item_playlist.view.playlist_frame
|
||||
import kotlinx.android.synthetic.main.item_playlist.view.playlist_title
|
||||
import kotlinx.android.synthetic.main.item_playlist.view.playlist_tracks
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
class PlaylistsAdapter(
|
||||
|
@ -30,7 +28,10 @@ class PlaylistsAdapter(
|
|||
|
||||
override fun getActionMenuId() = R.menu.cab_playlists
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_playlist, parent)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = ItemPlaylistBinding.inflate(layoutInflater, parent, false)
|
||||
return createViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val playlist = items.getOrNull(position) ?: return
|
||||
|
@ -55,7 +56,7 @@ class PlaylistsAdapter(
|
|||
}
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
RemovePlaylistDialog(ctx) { delete ->
|
||||
RemovePlaylistDialog(context) { delete ->
|
||||
val ids = getSelectedItems().map { it.id } as ArrayList<Int>
|
||||
if (delete) {
|
||||
ensureBackgroundThread {
|
||||
|
@ -72,9 +73,9 @@ class PlaylistsAdapter(
|
|||
private fun deletePlaylistSongs(ids: ArrayList<Int>, callback: () -> Unit) {
|
||||
var cnt = ids.size
|
||||
ids.map { id ->
|
||||
val paths = ctx.audioHelper.getPlaylistTracks(id).map { it.path }
|
||||
val paths = context.audioHelper.getPlaylistTracks(id).map { it.path }
|
||||
val fileDirItems = paths.map { FileDirItem(it, it.getFilenameFromPath()) } as ArrayList<FileDirItem>
|
||||
ctx.deleteFiles(fileDirItems) {
|
||||
context.deleteFiles(fileDirItems) {
|
||||
if (--cnt <= 0) {
|
||||
callback()
|
||||
}
|
||||
|
@ -97,8 +98,8 @@ class PlaylistsAdapter(
|
|||
items.removeAll(playlistsToDelete.toSet())
|
||||
|
||||
ensureBackgroundThread {
|
||||
ctx.audioHelper.deletePlaylists(playlistsToDelete)
|
||||
ctx.runOnUiThread {
|
||||
context.audioHelper.deletePlaylists(playlistsToDelete)
|
||||
context.runOnUiThread {
|
||||
removeSelectedItems(positions)
|
||||
}
|
||||
|
||||
|
@ -109,25 +110,25 @@ class PlaylistsAdapter(
|
|||
private fun getItemWithKey(key: Int): Playlist? = items.firstOrNull { it.id == key }
|
||||
|
||||
private fun showRenameDialog() {
|
||||
NewPlaylistDialog(ctx, items[getItemKeyPosition(selectedKeys.first())]) {
|
||||
ctx.runOnUiThread {
|
||||
NewPlaylistDialog(context, items[getItemKeyPosition(selectedKeys.first())]) {
|
||||
context.runOnUiThread {
|
||||
finishActMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupView(view: View, playlist: Playlist) {
|
||||
view.apply {
|
||||
setupViewBackground(ctx)
|
||||
playlist_frame?.isSelected = selectedKeys.contains(playlist.id)
|
||||
playlist_title.text = if (textToHighlight.isEmpty()) playlist.title else playlist.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
playlist_title.setTextColor(textColor)
|
||||
ItemPlaylistBinding.bind(view).apply {
|
||||
root.setupViewBackground(context)
|
||||
playlistFrame.isSelected = selectedKeys.contains(playlist.hashCode())
|
||||
playlistTitle.text = if (textToHighlight.isEmpty()) playlist.title else playlist.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
playlistTitle.setTextColor(textColor)
|
||||
|
||||
val tracks = resources.getQuantityString(R.plurals.tracks_plural, playlist.trackCount, playlist.trackCount)
|
||||
playlist_tracks.text = tracks
|
||||
playlist_tracks.setTextColor(textColor)
|
||||
playlistTracks.text = tracks
|
||||
playlistTracks.setTextColor(textColor)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(ctx.config.playlistSorting) ?: ""
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(context.config.playlistSorting) ?: ""
|
||||
}
|
||||
|
|
|
@ -17,14 +17,11 @@ import com.simplemobiletools.commons.interfaces.StartReorderDragListener
|
|||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemTrackQueueBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.helpers.EXTRA_SHUFFLE_INDICES
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import com.simplemobiletools.musicplayer.playback.CustomCommands
|
||||
import kotlinx.android.synthetic.main.item_track_queue.view.track_queue_drag_handle
|
||||
import kotlinx.android.synthetic.main.item_track_queue.view.track_queue_duration
|
||||
import kotlinx.android.synthetic.main.item_track_queue.view.track_queue_frame
|
||||
import kotlinx.android.synthetic.main.item_track_queue.view.track_queue_title
|
||||
|
||||
class QueueAdapter(activity: SimpleActivity, items: ArrayList<Track>, var currentTrack: Track? = null, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) :
|
||||
BaseMusicAdapter<Track>(items, activity, recyclerView, itemClick), ItemTouchHelperContract, RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
|
@ -46,7 +43,10 @@ class QueueAdapter(activity: SimpleActivity, items: ArrayList<Track>, var curren
|
|||
|
||||
override fun getActionMenuId() = R.menu.cab_queue
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_track_queue, parent)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = ItemTrackQueueBinding.inflate(layoutInflater, parent, false)
|
||||
return createViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = items.getOrNull(position) ?: return
|
||||
|
@ -75,7 +75,7 @@ class QueueAdapter(activity: SimpleActivity, items: ArrayList<Track>, var curren
|
|||
override fun onActionModeDestroyed() = notifyDataChanged()
|
||||
|
||||
fun updateCurrentTrack() {
|
||||
ctx.withPlayer {
|
||||
context.withPlayer {
|
||||
val track = currentMediaItem?.toTrack()
|
||||
if (track != null) {
|
||||
val lastTrackId = currentTrack?.mediaStoreId
|
||||
|
@ -101,13 +101,13 @@ class QueueAdapter(activity: SimpleActivity, items: ArrayList<Track>, var curren
|
|||
}
|
||||
}
|
||||
|
||||
ctx.removeQueueItems(selectedTracks) {
|
||||
context.removeQueueItems(selectedTracks) {
|
||||
refreshTracksList(positions)
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteTracks() {
|
||||
ConfirmationDialog(ctx, "", R.string.delete_song_warning, R.string.ok, R.string.cancel) {
|
||||
ConfirmationDialog(context, "", R.string.delete_song_warning, com.simplemobiletools.commons.R.string.ok, com.simplemobiletools.commons.R.string.cancel) {
|
||||
val positions = ArrayList<Int>()
|
||||
val selectedTracks = getSelectedTracks()
|
||||
selectedTracks.forEach { track ->
|
||||
|
@ -117,14 +117,14 @@ class QueueAdapter(activity: SimpleActivity, items: ArrayList<Track>, var curren
|
|||
}
|
||||
}
|
||||
|
||||
ctx.deleteTracks(selectedTracks) {
|
||||
context.deleteTracks(selectedTracks) {
|
||||
refreshTracksList(positions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshTracksList(positions: ArrayList<Int>) {
|
||||
ctx.runOnUiThread {
|
||||
context.runOnUiThread {
|
||||
positions.sortDescending()
|
||||
positions.forEach {
|
||||
items.removeAt(it)
|
||||
|
@ -132,41 +132,45 @@ class QueueAdapter(activity: SimpleActivity, items: ArrayList<Track>, var curren
|
|||
|
||||
removeSelectedItems(positions)
|
||||
if (items.isEmpty()) {
|
||||
ctx.finish()
|
||||
context.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun setupView(view: View, track: Track, holder: ViewHolder) {
|
||||
view.apply {
|
||||
setupViewBackground(ctx)
|
||||
track_queue_frame?.isSelected = selectedKeys.contains(track.hashCode())
|
||||
track_queue_title.text = if (textToHighlight.isEmpty()) track.title else track.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
ItemTrackQueueBinding.bind(view).apply {
|
||||
root.setupViewBackground(context)
|
||||
trackQueueFrame.isSelected = selectedKeys.contains(track.hashCode())
|
||||
trackQueueTitle.text = if (textToHighlight.isEmpty()) track.title else track.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
|
||||
arrayOf(track_queue_title, track_queue_duration).forEach {
|
||||
val color = if (track.mediaStoreId == currentTrack?.mediaStoreId) context.getProperPrimaryColor() else textColor
|
||||
arrayOf(trackQueueTitle, trackQueueDuration).forEach {
|
||||
val color = if (track.mediaStoreId == currentTrack?.mediaStoreId) {
|
||||
activity.getProperPrimaryColor()
|
||||
} else {
|
||||
textColor
|
||||
}
|
||||
it.setTextColor(color)
|
||||
}
|
||||
|
||||
track_queue_duration.text = track.duration.getFormattedDuration()
|
||||
track_queue_drag_handle.beVisibleIf(selectedKeys.isNotEmpty())
|
||||
track_queue_drag_handle.applyColorFilter(textColor)
|
||||
track_queue_drag_handle.setOnTouchListener { _, event ->
|
||||
trackQueueDuration.text = track.duration.getFormattedDuration()
|
||||
trackQueueDragHandle.beVisibleIf(selectedKeys.isNotEmpty())
|
||||
trackQueueDragHandle.applyColorFilter(textColor)
|
||||
trackQueueDragHandle.setOnTouchListener { _, event ->
|
||||
if (event.action == MotionEvent.ACTION_DOWN) {
|
||||
startReorderDragListener.requestDrag(holder)
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
ctx.getTrackCoverArt(track) { coverArt ->
|
||||
loadImage(findViewById(R.id.track_queue_image), coverArt, placeholderBig)
|
||||
context.getTrackCoverArt(track) { coverArt ->
|
||||
loadImage(trackQueueImage, coverArt, placeholderBig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateItems(newItems: ArrayList<Track>, highlightText: String, forceUpdate: Boolean) {
|
||||
ctx.withPlayer {
|
||||
context.withPlayer {
|
||||
currentTrack = currentMediaItem?.toTrack()
|
||||
super.updateItems(newItems, highlightText, forceUpdate)
|
||||
}
|
||||
|
@ -182,14 +186,14 @@ class QueueAdapter(activity: SimpleActivity, items: ArrayList<Track>, var curren
|
|||
|
||||
override fun onRowSelected(myViewHolder: ViewHolder?) {}
|
||||
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(ctx.config.trackSorting) ?: ""
|
||||
override fun onChange(position: Int) = items.getOrNull(position)?.getBubbleText(context.config.trackSorting) ?: ""
|
||||
|
||||
/**
|
||||
* [MediaController.moveMediaItem] is the proper way to move media items but it doesn't work when shuffle mode is enabled. This method modifies
|
||||
* the shuffle order when shuffle mode is enabled and defaults to [MediaController.moveMediaItem] otherwise.
|
||||
*/
|
||||
private fun swapMediaItemInQueue(fromPosition: Int, toPosition: Int) {
|
||||
ctx.withPlayer {
|
||||
context.withPlayer {
|
||||
if (shuffleModeEnabled) {
|
||||
val indices = shuffledMediaItemsIndices.toMutableList()
|
||||
indices.swap(fromPosition, toPosition)
|
||||
|
|
|
@ -17,6 +17,7 @@ import com.simplemobiletools.commons.interfaces.ItemTouchHelperContract
|
|||
import com.simplemobiletools.commons.interfaces.StartReorderDragListener
|
||||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemTrackBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.EditDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.helpers.ALL_TRACKS_PLAYLIST_ID
|
||||
|
@ -25,7 +26,6 @@ import com.simplemobiletools.musicplayer.inlines.indexOfFirstOrNull
|
|||
import com.simplemobiletools.musicplayer.models.Events
|
||||
import com.simplemobiletools.musicplayer.models.Playlist
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import kotlinx.android.synthetic.main.item_track.view.*
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
class TracksAdapter(
|
||||
|
@ -42,8 +42,6 @@ class TracksAdapter(
|
|||
private var startReorderDragListener: StartReorderDragListener
|
||||
|
||||
init {
|
||||
setupDragListener(true)
|
||||
|
||||
touchHelper = ItemTouchHelper(ItemMoveCallback(this))
|
||||
touchHelper!!.attachToRecyclerView(recyclerView)
|
||||
|
||||
|
@ -56,7 +54,10 @@ class TracksAdapter(
|
|||
|
||||
override fun getActionMenuId() = R.menu.cab_tracks
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = createViewHolder(R.layout.item_track, parent)
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val binding = ItemTrackBinding.inflate(layoutInflater, parent, false)
|
||||
return createViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val track = items.getOrNull(position) ?: return
|
||||
|
@ -115,18 +116,18 @@ class TracksAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
ctx.audioHelper.deleteTracks(selectedTracks)
|
||||
context.audioHelper.deleteTracks(selectedTracks)
|
||||
// this is to make sure these tracks aren't automatically re-added to the 'All tracks' playlist on rescan
|
||||
val removedTrackIds = selectedTracks.filter { it.playListId == ALL_TRACKS_PLAYLIST_ID }.map { it.mediaStoreId.toString() }
|
||||
if (removedTrackIds.isNotEmpty()) {
|
||||
val config = ctx.config
|
||||
val config = context.config
|
||||
config.tracksRemovedFromAllTracksPlaylist = config.tracksRemovedFromAllTracksPlaylist.apply {
|
||||
addAll(removedTrackIds)
|
||||
}
|
||||
}
|
||||
|
||||
EventBus.getDefault().post(Events.PlaylistsUpdated())
|
||||
ctx.runOnUiThread {
|
||||
context.runOnUiThread {
|
||||
positions.sortDescending()
|
||||
removeSelectedItems(positions)
|
||||
positions.forEach {
|
||||
|
@ -137,7 +138,7 @@ class TracksAdapter(
|
|||
}
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
ConfirmationDialog(ctx) {
|
||||
ConfirmationDialog(context) {
|
||||
ensureBackgroundThread {
|
||||
val positions = ArrayList<Int>()
|
||||
val selectedTracks = getSelectedTracks()
|
||||
|
@ -148,8 +149,8 @@ class TracksAdapter(
|
|||
}
|
||||
}
|
||||
|
||||
ctx.deleteTracks(selectedTracks) {
|
||||
ctx.runOnUiThread {
|
||||
context.deleteTracks(selectedTracks) {
|
||||
context.runOnUiThread {
|
||||
positions.sortDescending()
|
||||
removeSelectedItems(positions)
|
||||
positions.forEach {
|
||||
|
@ -162,7 +163,7 @@ class TracksAdapter(
|
|||
|
||||
// finish activity if all tracks are deleted
|
||||
if (items.isEmpty() && !isPlaylistContent()) {
|
||||
ctx.finish()
|
||||
context.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,45 +175,45 @@ class TracksAdapter(
|
|||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun setupView(view: View, track: Track, holder: ViewHolder) {
|
||||
view.apply {
|
||||
setupViewBackground(ctx)
|
||||
track_frame?.isSelected = selectedKeys.contains(track.hashCode())
|
||||
track_title.text = if (textToHighlight.isEmpty()) track.title else track.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
track_info.text = if (textToHighlight.isEmpty()) {
|
||||
ItemTrackBinding.bind(view).apply {
|
||||
root.setupViewBackground(context)
|
||||
trackFrame.isSelected = selectedKeys.contains(track.hashCode())
|
||||
trackTitle.text = if (textToHighlight.isEmpty()) track.title else track.title.highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
trackInfo.text = if (textToHighlight.isEmpty()) {
|
||||
"${track.artist} • ${track.album}"
|
||||
} else {
|
||||
("${track.artist} • ${track.album}").highlightTextPart(textToHighlight, properPrimaryColor)
|
||||
}
|
||||
track_drag_handle.beVisibleIf(isPlaylistContent() && selectedKeys.isNotEmpty())
|
||||
track_drag_handle.applyColorFilter(textColor)
|
||||
track_drag_handle.setOnTouchListener { _, event ->
|
||||
trackDragHandle.beVisibleIf(isPlaylistContent() && selectedKeys.isNotEmpty())
|
||||
trackDragHandle.applyColorFilter(textColor)
|
||||
trackDragHandle.setOnTouchListener { _, event ->
|
||||
if (event.action == MotionEvent.ACTION_DOWN) {
|
||||
startReorderDragListener.requestDrag(holder)
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
arrayOf(track_id, track_title, track_info, track_duration).forEach {
|
||||
arrayOf(trackId, trackTitle, trackInfo, trackDuration).forEach {
|
||||
it.setTextColor(textColor)
|
||||
}
|
||||
|
||||
track_duration.text = track.duration.getFormattedDuration()
|
||||
context.getTrackCoverArt(track) { coverArt ->
|
||||
loadImage(findViewById(R.id.track_image), coverArt, placeholderBig)
|
||||
trackDuration.text = track.duration.getFormattedDuration()
|
||||
activity.getTrackCoverArt(track) { coverArt ->
|
||||
loadImage(trackImage, coverArt, placeholderBig)
|
||||
}
|
||||
|
||||
track_image.beVisible()
|
||||
track_id.beGone()
|
||||
trackImage.beVisible()
|
||||
trackId.beGone()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChange(position: Int): String {
|
||||
val sorting = if (isPlaylistContent() && playlist != null) {
|
||||
ctx.config.getProperPlaylistSorting(playlist.id)
|
||||
context.config.getProperPlaylistSorting(playlist.id)
|
||||
} else if (sourceType == TYPE_FOLDER && folder != null) {
|
||||
ctx.config.getProperFolderSorting(folder)
|
||||
context.config.getProperFolderSorting(folder)
|
||||
} else {
|
||||
ctx.config.trackSorting
|
||||
context.config.trackSorting
|
||||
}
|
||||
|
||||
return items.getOrNull(position)?.getBubbleText(sorting) ?: ""
|
||||
|
@ -220,19 +221,19 @@ class TracksAdapter(
|
|||
|
||||
private fun displayEditDialog() {
|
||||
getSelectedTracks().firstOrNull()?.let { selectedTrack ->
|
||||
EditDialog(ctx, selectedTrack) { track ->
|
||||
EditDialog(context, selectedTrack) { track ->
|
||||
val trackIndex = items.indexOfFirstOrNull { it.mediaStoreId == track.mediaStoreId } ?: return@EditDialog
|
||||
items[trackIndex] = track
|
||||
notifyItemChanged(trackIndex)
|
||||
finishActMode()
|
||||
|
||||
ctx.refreshQueueAndTracks(track)
|
||||
context.refreshQueueAndTracks(track)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRowMoved(fromPosition: Int, toPosition: Int) {
|
||||
ctx.config.saveCustomPlaylistSorting(playlist!!.id, PLAYER_SORT_BY_CUSTOM)
|
||||
context.config.saveCustomPlaylistSorting(playlist!!.id, PLAYER_SORT_BY_CUSTOM)
|
||||
items.swap(fromPosition, toPosition)
|
||||
notifyItemMoved(fromPosition, toPosition)
|
||||
}
|
||||
|
@ -244,7 +245,7 @@ class TracksAdapter(
|
|||
var index = 0
|
||||
items.forEach {
|
||||
it.orderInPlaylist = index++
|
||||
ctx.audioHelper.updateOrderInPlaylist(index, it.id)
|
||||
context.audioHelper.updateOrderInPlaylist(index, it.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.annotation.SuppressLint
|
|||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller
|
||||
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
||||
import com.simplemobiletools.commons.extensions.beGone
|
||||
|
@ -15,15 +14,13 @@ import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
|||
import com.simplemobiletools.commons.views.MyRecyclerView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemAlbumHeaderBinding
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemTrackBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.EditDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.models.AlbumHeader
|
||||
import com.simplemobiletools.musicplayer.models.ListItem
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import kotlinx.android.synthetic.main.item_album_header.view.album_artist
|
||||
import kotlinx.android.synthetic.main.item_album_header.view.album_meta
|
||||
import kotlinx.android.synthetic.main.item_album_header.view.album_title
|
||||
import kotlinx.android.synthetic.main.item_track.view.*
|
||||
|
||||
class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList<ListItem>, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) :
|
||||
BaseMusicAdapter<ListItem>(items, activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate {
|
||||
|
@ -31,17 +28,17 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList<ListItem>,
|
|||
private val ITEM_HEADER = 0
|
||||
private val ITEM_TRACK = 1
|
||||
|
||||
override val cornerRadius = resources.getDimension(R.dimen.rounded_corner_radius_big).toInt()
|
||||
override val cornerRadius = resources.getDimension(com.simplemobiletools.commons.R.dimen.rounded_corner_radius_big).toInt()
|
||||
|
||||
override fun getActionMenuId() = R.menu.cab_tracks_header
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val layout = when (viewType) {
|
||||
ITEM_HEADER -> R.layout.item_album_header
|
||||
else -> R.layout.item_track
|
||||
val binding = when (viewType) {
|
||||
ITEM_HEADER -> ItemAlbumHeaderBinding.inflate(layoutInflater, parent, false)
|
||||
else -> ItemTrackBinding.inflate(layoutInflater, parent, false)
|
||||
}
|
||||
|
||||
return createViewHolder(layout, parent)
|
||||
return createViewHolder(binding.root)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
|
@ -92,7 +89,7 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList<ListItem>,
|
|||
override fun getIsItemSelectable(position: Int) = position != 0
|
||||
|
||||
private fun askConfirmDelete() {
|
||||
ConfirmationDialog(ctx) {
|
||||
ConfirmationDialog(context) {
|
||||
ensureBackgroundThread {
|
||||
val positions = ArrayList<Int>()
|
||||
val selectedTracks = getSelectedTracks()
|
||||
|
@ -103,8 +100,8 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList<ListItem>,
|
|||
}
|
||||
}
|
||||
|
||||
ctx.deleteTracks(selectedTracks) {
|
||||
ctx.runOnUiThread {
|
||||
context.deleteTracks(selectedTracks) {
|
||||
context.runOnUiThread {
|
||||
positions.sortDescending()
|
||||
removeSelectedItems(positions)
|
||||
positions.forEach {
|
||||
|
@ -113,7 +110,7 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList<ListItem>,
|
|||
|
||||
// finish activity if all tracks are deleted
|
||||
if (items.none { it is Track }) {
|
||||
ctx.finish()
|
||||
context.finish()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,27 +119,27 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList<ListItem>,
|
|||
}
|
||||
|
||||
private fun setupTrack(view: View, track: Track) {
|
||||
view.apply {
|
||||
setupViewBackground(ctx)
|
||||
track_frame?.isSelected = selectedKeys.contains(track.hashCode())
|
||||
track_title.text = track.title
|
||||
track_info.beGone()
|
||||
ItemTrackBinding.bind(view).apply {
|
||||
root.setupViewBackground(context)
|
||||
trackFrame.isSelected = selectedKeys.contains(track.hashCode())
|
||||
trackTitle.text = track.title
|
||||
trackInfo.beGone()
|
||||
|
||||
arrayOf(track_id, track_title, track_duration).forEach {
|
||||
arrayOf(trackId, trackTitle, trackDuration).forEach {
|
||||
it.setTextColor(textColor)
|
||||
}
|
||||
|
||||
track_duration.text = track.duration.getFormattedDuration()
|
||||
track_id.text = track.trackId.toString()
|
||||
track_image.beGone()
|
||||
track_id.beVisible()
|
||||
trackDuration.text = track.duration.getFormattedDuration()
|
||||
trackId.text = track.trackId.toString()
|
||||
trackImage.beGone()
|
||||
trackId.beVisible()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupHeader(view: View, header: AlbumHeader) {
|
||||
view.apply {
|
||||
album_title.text = header.title
|
||||
album_artist.text = header.artist
|
||||
ItemAlbumHeaderBinding.bind(view).apply {
|
||||
albumTitle.text = header.title
|
||||
albumArtist.text = header.artist
|
||||
|
||||
val tracks = resources.getQuantityString(R.plurals.tracks_plural, header.trackCnt, header.trackCnt)
|
||||
var year = ""
|
||||
|
@ -151,21 +148,21 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList<ListItem>,
|
|||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
album_meta.text = "$year$tracks • ${header.duration.getFormattedDuration(true)}"
|
||||
albumMeta.text = "$year$tracks • ${header.duration.getFormattedDuration(true)}"
|
||||
|
||||
arrayOf(album_title, album_artist, album_meta).forEach {
|
||||
arrayOf(albumTitle, albumArtist, albumMeta).forEach {
|
||||
it.setTextColor(textColor)
|
||||
}
|
||||
|
||||
ensureBackgroundThread {
|
||||
val album = ctx.audioHelper.getAlbum(header.id)
|
||||
val album = context.audioHelper.getAlbum(header.id)
|
||||
if (album != null) {
|
||||
ctx.getAlbumCoverArt(album) { coverArt ->
|
||||
loadImage(findViewById(R.id.album_image), coverArt, placeholderBig)
|
||||
context.getAlbumCoverArt(album) { coverArt ->
|
||||
loadImage(albumImage, coverArt, placeholderBig)
|
||||
}
|
||||
} else {
|
||||
ctx.runOnUiThread {
|
||||
findViewById<ImageView>(R.id.album_image).setImageDrawable(placeholderBig)
|
||||
context.runOnUiThread {
|
||||
albumImage.setImageDrawable(placeholderBig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +171,7 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList<ListItem>,
|
|||
|
||||
override fun onChange(position: Int): CharSequence {
|
||||
return when (val listItem = items.getOrNull(position)) {
|
||||
is Track -> listItem.getBubbleText(ctx.config.trackSorting)
|
||||
is Track -> listItem.getBubbleText(context.config.trackSorting)
|
||||
is AlbumHeader -> listItem.title
|
||||
else -> ""
|
||||
}
|
||||
|
@ -182,7 +179,7 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList<ListItem>,
|
|||
|
||||
private fun displayEditDialog() {
|
||||
getSelectedTracks().firstOrNull()?.let { selectedTrack ->
|
||||
EditDialog(ctx, selectedTrack) { track ->
|
||||
EditDialog(context, selectedTrack) { track ->
|
||||
val trackIndex = items.indexOfFirst { (it as? Track)?.mediaStoreId == track.mediaStoreId }
|
||||
if (trackIndex != -1) {
|
||||
items[trackIndex] = track
|
||||
|
@ -190,7 +187,7 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList<ListItem>,
|
|||
finishActMode()
|
||||
}
|
||||
|
||||
ctx.refreshQueueAndTracks(track)
|
||||
context.refreshQueueAndTracks(track)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,62 +5,59 @@ import android.view.ViewGroup
|
|||
import androidx.viewpager.widget.PagerAdapter
|
||||
import com.simplemobiletools.commons.extensions.getProperPrimaryColor
|
||||
import com.simplemobiletools.commons.extensions.getProperTextColor
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.databinding.*
|
||||
import com.simplemobiletools.musicplayer.extensions.getVisibleTabs
|
||||
import com.simplemobiletools.musicplayer.fragments.MyViewPagerFragment
|
||||
import com.simplemobiletools.musicplayer.fragments.PlaylistsFragment
|
||||
import com.simplemobiletools.musicplayer.fragments.TracksFragment
|
||||
import com.simplemobiletools.musicplayer.helpers.*
|
||||
|
||||
class ViewPagerAdapter(val activity: SimpleActivity) : PagerAdapter() {
|
||||
val showTabs = activity.config.showTabs
|
||||
private val fragments = arrayListOf<MyViewPagerFragment>()
|
||||
private var primaryItem: MyViewPagerFragment? = null
|
||||
|
||||
override fun instantiateItem(container: ViewGroup, position: Int): Any {
|
||||
val layout = getFragment(position)
|
||||
val view = activity.layoutInflater.inflate(layout, container, false)
|
||||
container.addView(view)
|
||||
|
||||
(view as MyViewPagerFragment).apply {
|
||||
return getFragment(position, container).apply {
|
||||
fragments.add(this)
|
||||
container.addView(this)
|
||||
setupFragment(activity)
|
||||
setupColors(activity.getProperTextColor(), activity.getProperPrimaryColor())
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
override fun destroyItem(container: ViewGroup, position: Int, item: Any) {
|
||||
fragments.remove(item)
|
||||
container.removeView(item as View)
|
||||
}
|
||||
|
||||
override fun getCount() = tabsList.filter { it and showTabs != 0 }.size
|
||||
override fun setPrimaryItem(container: ViewGroup, position: Int, `object`: Any) {
|
||||
primaryItem = `object` as MyViewPagerFragment
|
||||
}
|
||||
|
||||
override fun getCount() = activity.getVisibleTabs().size
|
||||
|
||||
override fun isViewFromObject(view: View, item: Any) = view == item
|
||||
|
||||
private fun getFragment(position: Int): Int {
|
||||
val fragments = arrayListOf<Int>()
|
||||
if (showTabs and TAB_PLAYLISTS != 0) {
|
||||
fragments.add(R.layout.fragment_playlists)
|
||||
private fun getFragment(position: Int, container: ViewGroup): MyViewPagerFragment {
|
||||
val tab = activity.getVisibleTabs()[position]
|
||||
val layoutInflater = activity.layoutInflater
|
||||
return when (tab) {
|
||||
TAB_PLAYLISTS -> FragmentPlaylistsBinding.inflate(layoutInflater, container, false).root
|
||||
TAB_FOLDERS -> FragmentFoldersBinding.inflate(layoutInflater, container, false).root
|
||||
TAB_ARTISTS -> FragmentArtistsBinding.inflate(layoutInflater, container, false).root
|
||||
TAB_ALBUMS -> FragmentAlbumsBinding.inflate(layoutInflater, container, false).root
|
||||
TAB_TRACKS -> FragmentTracksBinding.inflate(layoutInflater, container, false).root
|
||||
TAB_GENRES -> FragmentGenresBinding.inflate(layoutInflater, container, false).root
|
||||
else -> throw IllegalArgumentException("Unknown tab: $tab")
|
||||
}
|
||||
|
||||
if (showTabs and TAB_FOLDERS != 0) {
|
||||
fragments.add(R.layout.fragment_folders)
|
||||
}
|
||||
|
||||
if (showTabs and TAB_ARTISTS != 0) {
|
||||
fragments.add(R.layout.fragment_artists)
|
||||
}
|
||||
|
||||
if (showTabs and TAB_ALBUMS != 0) {
|
||||
fragments.add(R.layout.fragment_albums)
|
||||
}
|
||||
|
||||
if (showTabs and TAB_TRACKS != 0) {
|
||||
fragments.add(R.layout.fragment_tracks)
|
||||
}
|
||||
|
||||
if (showTabs and TAB_GENRES != 0) {
|
||||
fragments.add(R.layout.fragment_genres)
|
||||
}
|
||||
|
||||
return fragments[position]
|
||||
}
|
||||
|
||||
fun getAllFragments() = fragments
|
||||
|
||||
fun getCurrentFragment() = primaryItem
|
||||
|
||||
fun getPlaylistsFragment() = fragments.find { it is PlaylistsFragment }
|
||||
|
||||
fun getTracksFragment() = fragments.find { it is TracksFragment }
|
||||
}
|
||||
|
|
|
@ -1,36 +1,36 @@
|
|||
package com.simplemobiletools.musicplayer.dialogs
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RadioGroup
|
||||
import com.simplemobiletools.commons.extensions.beVisibleIf
|
||||
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
|
||||
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
||||
import com.simplemobiletools.commons.extensions.viewBinding
|
||||
import com.simplemobiletools.commons.helpers.SORT_DESCENDING
|
||||
import com.simplemobiletools.commons.models.RadioItem
|
||||
import com.simplemobiletools.commons.views.MyCompatRadioButton
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.DialogChangeSortingBinding
|
||||
import com.simplemobiletools.musicplayer.databinding.SmallRadioButtonBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.helpers.*
|
||||
import com.simplemobiletools.musicplayer.models.Playlist
|
||||
import kotlinx.android.synthetic.main.dialog_change_sorting.view.*
|
||||
|
||||
class ChangeSortingDialog(val activity: Activity, val location: Int, val playlist: Playlist? = null, val path: String? = null, val callback: () -> Unit) {
|
||||
private val config = activity.config
|
||||
private var currSorting = 0
|
||||
private val view: View
|
||||
private val binding by activity.viewBinding(DialogChangeSortingBinding::inflate)
|
||||
|
||||
init {
|
||||
view = activity.layoutInflater.inflate(R.layout.dialog_change_sorting, null).apply {
|
||||
use_for_this_playlist_divider.beVisibleIf(playlist != null || path != null)
|
||||
sorting_dialog_use_for_this_only.beVisibleIf(playlist != null || path != null)
|
||||
binding.apply {
|
||||
useForThisPlaylistDivider.beVisibleIf(playlist != null || path != null)
|
||||
sortingDialogUseForThisOnly.beVisibleIf(playlist != null || path != null)
|
||||
|
||||
if (playlist != null) {
|
||||
sorting_dialog_use_for_this_only.isChecked = config.hasCustomPlaylistSorting(playlist.id)
|
||||
sortingDialogUseForThisOnly.isChecked = config.hasCustomPlaylistSorting(playlist.id)
|
||||
} else if (path != null) {
|
||||
sorting_dialog_use_for_this_only.text = activity.getString(R.string.use_for_this_folder)
|
||||
sorting_dialog_use_for_this_only.isChecked = config.hasCustomSorting(path)
|
||||
sortingDialogUseForThisOnly.text = activity.getString(com.simplemobiletools.commons.R.string.use_for_this_folder)
|
||||
sortingDialogUseForThisOnly.isChecked = config.hasCustomSorting(path)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,10 +54,10 @@ class ChangeSortingDialog(val activity: Activity, val location: Int, val playlis
|
|||
setupOrderRadio()
|
||||
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() }
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(com.simplemobiletools.commons.R.string.ok) { _, _ -> dialogConfirmed() }
|
||||
.setNegativeButton(com.simplemobiletools.commons.R.string.cancel, null)
|
||||
.apply {
|
||||
activity.setupDialogStuff(view, this, R.string.sort_by)
|
||||
activity.setupDialogStuff(binding.root, this, com.simplemobiletools.commons.R.string.sort_by)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,59 +65,64 @@ class ChangeSortingDialog(val activity: Activity, val location: Int, val playlis
|
|||
val radioItems = ArrayList<RadioItem>()
|
||||
when (location) {
|
||||
TAB_PLAYLISTS, TAB_FOLDERS -> {
|
||||
radioItems.add(RadioItem(0, activity.getString(R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(0, activity.getString(com.simplemobiletools.commons.R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(1, activity.getString(R.string.track_count), PLAYER_SORT_BY_TRACK_COUNT))
|
||||
}
|
||||
|
||||
TAB_ARTISTS -> {
|
||||
radioItems.add(RadioItem(0, activity.getString(R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(0, activity.getString(com.simplemobiletools.commons.R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(1, activity.getString(R.string.album_count), PLAYER_SORT_BY_ALBUM_COUNT))
|
||||
radioItems.add(RadioItem(2, activity.getString(R.string.track_count), PLAYER_SORT_BY_TRACK_COUNT))
|
||||
}
|
||||
|
||||
TAB_ALBUMS -> {
|
||||
radioItems.add(RadioItem(0, activity.getString(R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(0, activity.getString(com.simplemobiletools.commons.R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(1, activity.getString(R.string.artist_name), PLAYER_SORT_BY_ARTIST_TITLE))
|
||||
radioItems.add(RadioItem(2, activity.getString(R.string.year), PLAYER_SORT_BY_YEAR))
|
||||
radioItems.add(RadioItem(4, activity.getString(R.string.date_added), PLAYER_SORT_BY_DATE_ADDED))
|
||||
radioItems.add(RadioItem(4, activity.getString(com.simplemobiletools.commons.R.string.date_added), PLAYER_SORT_BY_DATE_ADDED))
|
||||
}
|
||||
|
||||
TAB_TRACKS -> {
|
||||
radioItems.add(RadioItem(0, activity.getString(R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(1, activity.getString(R.string.artist), PLAYER_SORT_BY_ARTIST_TITLE))
|
||||
radioItems.add(RadioItem(2, activity.getString(R.string.duration), PLAYER_SORT_BY_DURATION))
|
||||
radioItems.add(RadioItem(0, activity.getString(com.simplemobiletools.commons.R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(1, activity.getString(com.simplemobiletools.commons.R.string.artist), PLAYER_SORT_BY_ARTIST_TITLE))
|
||||
radioItems.add(RadioItem(2, activity.getString(com.simplemobiletools.commons.R.string.duration), PLAYER_SORT_BY_DURATION))
|
||||
radioItems.add(RadioItem(3, activity.getString(R.string.track_number), PLAYER_SORT_BY_TRACK_ID))
|
||||
radioItems.add(RadioItem(4, activity.getString(R.string.date_added), PLAYER_SORT_BY_DATE_ADDED))
|
||||
radioItems.add(RadioItem(4, activity.getString(com.simplemobiletools.commons.R.string.date_added), PLAYER_SORT_BY_DATE_ADDED))
|
||||
}
|
||||
|
||||
TAB_GENRES -> {
|
||||
radioItems.add(RadioItem(0, activity.getString(R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(0, activity.getString(com.simplemobiletools.commons.R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(2, activity.getString(R.string.track_count), PLAYER_SORT_BY_TRACK_COUNT))
|
||||
}
|
||||
|
||||
ACTIVITY_PLAYLIST_FOLDER -> {
|
||||
radioItems.add(RadioItem(0, activity.getString(R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(1, activity.getString(R.string.artist), PLAYER_SORT_BY_ARTIST_TITLE))
|
||||
radioItems.add(RadioItem(2, activity.getString(R.string.duration), PLAYER_SORT_BY_DURATION))
|
||||
radioItems.add(RadioItem(0, activity.getString(com.simplemobiletools.commons.R.string.title), PLAYER_SORT_BY_TITLE))
|
||||
radioItems.add(RadioItem(1, activity.getString(com.simplemobiletools.commons.R.string.artist), PLAYER_SORT_BY_ARTIST_TITLE))
|
||||
radioItems.add(RadioItem(2, activity.getString(com.simplemobiletools.commons.R.string.duration), PLAYER_SORT_BY_DURATION))
|
||||
radioItems.add(RadioItem(3, activity.getString(R.string.track_number), PLAYER_SORT_BY_TRACK_ID))
|
||||
radioItems.add(RadioItem(4, activity.getString(R.string.date_added), PLAYER_SORT_BY_DATE_ADDED))
|
||||
radioItems.add(RadioItem(4, activity.getString(com.simplemobiletools.commons.R.string.date_added), PLAYER_SORT_BY_DATE_ADDED))
|
||||
|
||||
if (playlist != null) {
|
||||
radioItems.add(RadioItem(4, activity.getString(R.string.custom), PLAYER_SORT_BY_CUSTOM))
|
||||
radioItems.add(RadioItem(4, activity.getString(com.simplemobiletools.commons.R.string.custom), PLAYER_SORT_BY_CUSTOM))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
view.sorting_dialog_radio_sorting.setOnCheckedChangeListener { group, checkedId ->
|
||||
view.sorting_order_divider.beVisibleIf(checkedId != PLAYER_SORT_BY_CUSTOM)
|
||||
view.sorting_dialog_radio_order.beVisibleIf(checkedId != PLAYER_SORT_BY_CUSTOM)
|
||||
binding.sortingDialogRadioSorting.setOnCheckedChangeListener { _, checkedId ->
|
||||
binding.sortingOrderDivider.beVisibleIf(checkedId != PLAYER_SORT_BY_CUSTOM)
|
||||
binding.sortingDialogRadioOrder.beVisibleIf(checkedId != PLAYER_SORT_BY_CUSTOM)
|
||||
}
|
||||
|
||||
radioItems.forEach { radioItem ->
|
||||
activity.layoutInflater.inflate(R.layout.small_radio_button, null).apply {
|
||||
findViewById<MyCompatRadioButton>(R.id.small_radio_button).apply {
|
||||
SmallRadioButtonBinding.inflate(activity.layoutInflater).apply {
|
||||
smallRadioButton.apply {
|
||||
text = radioItem.title
|
||||
isChecked = currSorting and (radioItem.value as Int) != 0
|
||||
id = radioItem.value as Int
|
||||
}
|
||||
|
||||
view.sorting_dialog_radio_sorting.addView(
|
||||
this,
|
||||
binding.sortingDialogRadioSorting.addView(
|
||||
smallRadioButton,
|
||||
RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
)
|
||||
}
|
||||
|
@ -125,21 +130,20 @@ class ChangeSortingDialog(val activity: Activity, val location: Int, val playlis
|
|||
}
|
||||
|
||||
private fun setupOrderRadio() {
|
||||
val orderRadio = view.sorting_dialog_radio_order
|
||||
var orderBtn = orderRadio.sorting_dialog_radio_ascending
|
||||
var orderBtn = binding.sortingDialogRadioAscending
|
||||
|
||||
if (currSorting and SORT_DESCENDING != 0) {
|
||||
orderBtn = orderRadio.sorting_dialog_radio_descending
|
||||
orderBtn = binding.sortingDialogRadioDescending
|
||||
}
|
||||
|
||||
orderBtn.isChecked = true
|
||||
}
|
||||
|
||||
private fun dialogConfirmed() {
|
||||
val sortingRadio = view.sorting_dialog_radio_sorting
|
||||
val sortingRadio = binding.sortingDialogRadioSorting
|
||||
var sorting = sortingRadio.checkedRadioButtonId
|
||||
|
||||
if (view.sorting_dialog_radio_order.checkedRadioButtonId == R.id.sorting_dialog_radio_descending) {
|
||||
if (binding.sortingDialogRadioOrder.checkedRadioButtonId == R.id.sorting_dialog_radio_descending) {
|
||||
sorting = sorting or SORT_DESCENDING
|
||||
}
|
||||
|
||||
|
@ -152,7 +156,7 @@ class ChangeSortingDialog(val activity: Activity, val location: Int, val playlis
|
|||
TAB_TRACKS -> config.trackSorting = sorting
|
||||
TAB_GENRES -> config.genreSorting = sorting
|
||||
ACTIVITY_PLAYLIST_FOLDER -> {
|
||||
if (view.sorting_dialog_use_for_this_only.isChecked) {
|
||||
if (binding.sortingDialogUseForThisOnly.isChecked) {
|
||||
if (playlist != null) {
|
||||
config.saveCustomPlaylistSorting(playlist.id, sorting)
|
||||
} else if (path != null) {
|
||||
|
|
|
@ -6,41 +6,42 @@ import com.simplemobiletools.commons.extensions.*
|
|||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.commons.helpers.isRPlus
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.DialogRenameSongBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.helpers.TagHelper
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import kotlinx.android.synthetic.main.dialog_rename_song.view.*
|
||||
|
||||
class EditDialog(val activity: BaseSimpleActivity, val track: Track, val callback: (track: Track) -> Unit) {
|
||||
private val tagHelper = TagHelper(activity)
|
||||
private val binding by activity.viewBinding(DialogRenameSongBinding::inflate)
|
||||
|
||||
init {
|
||||
val view = activity.layoutInflater.inflate(R.layout.dialog_rename_song, null).apply {
|
||||
binding.apply {
|
||||
title.setText(track.title)
|
||||
artist.setText(track.artist)
|
||||
album.setText(track.album)
|
||||
val filename = track.path.getFilenameFromPath()
|
||||
file_name.setText(filename.substring(0, filename.lastIndexOf(".")))
|
||||
fileName.setText(filename.substring(0, filename.lastIndexOf(".")))
|
||||
extension.setText(track.path.getFilenameExtension())
|
||||
if (isRPlus()) {
|
||||
arrayOf(file_name_hint, extension_hint).forEach {
|
||||
arrayOf(fileNameHint, extensionHint).forEach {
|
||||
it.beGone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(com.simplemobiletools.commons.R.string.ok, null)
|
||||
.setNegativeButton(com.simplemobiletools.commons.R.string.cancel, null)
|
||||
.apply {
|
||||
activity.setupDialogStuff(view, this, R.string.rename_song) { alertDialog ->
|
||||
alertDialog.showKeyboard(view.title)
|
||||
activity.setupDialogStuff(binding.root, this, R.string.rename_song) { alertDialog ->
|
||||
alertDialog.showKeyboard(binding.title)
|
||||
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
||||
val newTitle = view.title.value
|
||||
val newArtist = view.artist.value
|
||||
val newAlbum = view.album.value
|
||||
val newFilename = view.file_name.value
|
||||
val newFileExtension = view.extension.value
|
||||
val newTitle = binding.title.value
|
||||
val newArtist = binding.artist.value
|
||||
val newAlbum = binding.album.value
|
||||
val newFilename = binding.fileName.value
|
||||
val newFileExtension = binding.extension.value
|
||||
|
||||
if (newTitle.isEmpty() || newArtist.isEmpty() || newFilename.isEmpty() || newFileExtension.isEmpty()) {
|
||||
activity.toast(R.string.rename_song_empty)
|
||||
|
@ -62,7 +63,7 @@ class EditDialog(val activity: BaseSimpleActivity, val track: Track, val callbac
|
|||
}
|
||||
|
||||
if (!isRPlus()) {
|
||||
activity.renameFile(oldPath, newPath, false) { success, andd ->
|
||||
activity.renameFile(oldPath, newPath, false) { success, _ ->
|
||||
if (success) {
|
||||
storeEditedSong(track, oldPath, newPath)
|
||||
track.path = newPath
|
||||
|
@ -104,7 +105,7 @@ class EditDialog(val activity: BaseSimpleActivity, val track: Track, val callbac
|
|||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
activity.toast(R.string.unknown_error_occurred)
|
||||
activity.toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
package com.simplemobiletools.musicplayer.dialogs
|
||||
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.simplemobiletools.commons.dialogs.FilePickerDialog
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.databinding.DialogExportPlaylistBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import kotlinx.android.synthetic.main.dialog_export_playlist.view.*
|
||||
import java.io.File
|
||||
|
||||
class ExportPlaylistDialog(
|
||||
|
@ -18,23 +17,24 @@ class ExportPlaylistDialog(
|
|||
private val callback: (file: File) -> Unit
|
||||
) {
|
||||
private var ignoreClicks = false
|
||||
private var realPath = if (path.isEmpty()) activity.internalStoragePath else path
|
||||
private var realPath = path.ifEmpty { activity.internalStoragePath }
|
||||
private val binding by activity.viewBinding(DialogExportPlaylistBinding::inflate)
|
||||
|
||||
init {
|
||||
val view = (activity.layoutInflater.inflate(R.layout.dialog_export_playlist, null) as ViewGroup).apply {
|
||||
export_playlist_folder.text = activity.humanizePath(realPath)
|
||||
binding.apply {
|
||||
exportPlaylistFolder.text = activity.humanizePath(realPath)
|
||||
|
||||
val fileName = "playlist_${activity.getCurrentFormattedDateTime()}"
|
||||
export_playlist_filename.setText(fileName)
|
||||
exportPlaylistFilename.setText(fileName)
|
||||
|
||||
if (hidePath) {
|
||||
export_playlist_folder_label.beGone()
|
||||
export_playlist_folder.beGone()
|
||||
exportPlaylistFolderLabel.beGone()
|
||||
exportPlaylistFolder.beGone()
|
||||
} else {
|
||||
export_playlist_folder.setOnClickListener {
|
||||
activity.hideKeyboard(export_playlist_filename)
|
||||
exportPlaylistFolder.setOnClickListener {
|
||||
activity.hideKeyboard(exportPlaylistFilename)
|
||||
FilePickerDialog(activity, realPath, false, showFAB = true) {
|
||||
export_playlist_folder.text = activity.humanizePath(it)
|
||||
exportPlaylistFolder.text = activity.humanizePath(it)
|
||||
realPath = it
|
||||
}
|
||||
}
|
||||
|
@ -42,18 +42,18 @@ class ExportPlaylistDialog(
|
|||
}
|
||||
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(com.simplemobiletools.commons.R.string.ok, null)
|
||||
.setNegativeButton(com.simplemobiletools.commons.R.string.cancel, null)
|
||||
.apply {
|
||||
activity.setupDialogStuff(view, this, R.string.export_playlist) { alertDialog ->
|
||||
activity.setupDialogStuff(binding.root, this, R.string.export_playlist) { alertDialog ->
|
||||
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
||||
val filename = view.export_playlist_filename.value
|
||||
val filename = binding.exportPlaylistFilename.value
|
||||
when {
|
||||
filename.isEmpty() -> activity.toast(R.string.empty_name)
|
||||
filename.isEmpty() -> activity.toast(com.simplemobiletools.commons.R.string.empty_name)
|
||||
filename.isAValidFilename() -> {
|
||||
val file = File(realPath, "$filename.m3u")
|
||||
if (!hidePath && file.exists()) {
|
||||
activity.toast(R.string.name_taken)
|
||||
activity.toast(com.simplemobiletools.commons.R.string.name_taken)
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,8 @@ class ExportPlaylistDialog(
|
|||
alertDialog.dismiss()
|
||||
}
|
||||
}
|
||||
else -> activity.toast(R.string.invalid_name)
|
||||
|
||||
else -> activity.toast(com.simplemobiletools.commons.R.string.invalid_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,49 +4,49 @@ import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
|||
import com.simplemobiletools.commons.extensions.beGone
|
||||
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
|
||||
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
||||
import com.simplemobiletools.commons.extensions.viewBinding
|
||||
import com.simplemobiletools.commons.helpers.isQPlus
|
||||
import com.simplemobiletools.commons.views.MyAppCompatCheckbox
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.DialogManageVisibleTabsBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.helpers.*
|
||||
import kotlinx.android.synthetic.main.dialog_manage_visible_tabs.view.manage_visible_tabs_folders
|
||||
|
||||
class ManageVisibleTabsDialog(val activity: BaseSimpleActivity, val callback: (result: Int) -> Unit) {
|
||||
private var view = activity.layoutInflater.inflate(R.layout.dialog_manage_visible_tabs, null)
|
||||
private val tabs = LinkedHashMap<Int, Int>()
|
||||
private val binding by activity.viewBinding(DialogManageVisibleTabsBinding::inflate)
|
||||
private val tabs = LinkedHashMap<Int, MyAppCompatCheckbox>()
|
||||
|
||||
init {
|
||||
tabs.apply {
|
||||
put(TAB_PLAYLISTS, R.id.manage_visible_tabs_playlists)
|
||||
put(TAB_FOLDERS, R.id.manage_visible_tabs_folders)
|
||||
put(TAB_ARTISTS, R.id.manage_visible_tabs_artists)
|
||||
put(TAB_ALBUMS, R.id.manage_visible_tabs_albums)
|
||||
put(TAB_TRACKS, R.id.manage_visible_tabs_tracks)
|
||||
put(TAB_GENRES, R.id.manage_visible_tabs_genres)
|
||||
put(TAB_PLAYLISTS, binding.manageVisibleTabsPlaylists)
|
||||
put(TAB_FOLDERS, binding.manageVisibleTabsFolders)
|
||||
put(TAB_ARTISTS, binding.manageVisibleTabsArtists)
|
||||
put(TAB_ALBUMS, binding.manageVisibleTabsAlbums)
|
||||
put(TAB_TRACKS, binding.manageVisibleTabsTracks)
|
||||
put(TAB_GENRES, binding.manageVisibleTabsGenres)
|
||||
}
|
||||
|
||||
if (!isQPlus()) {
|
||||
tabs.remove(TAB_FOLDERS)
|
||||
view.manage_visible_tabs_folders.beGone()
|
||||
binding.manageVisibleTabsFolders.beGone()
|
||||
}
|
||||
|
||||
val showTabs = activity.config.showTabs
|
||||
for ((key, value) in tabs) {
|
||||
view.findViewById<MyAppCompatCheckbox>(value).isChecked = showTabs and key != 0
|
||||
value.isChecked = showTabs and key != 0
|
||||
}
|
||||
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() }
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(com.simplemobiletools.commons.R.string.ok) { _, _ -> dialogConfirmed() }
|
||||
.setNegativeButton(com.simplemobiletools.commons.R.string.cancel, null)
|
||||
.apply {
|
||||
activity.setupDialogStuff(view, this)
|
||||
activity.setupDialogStuff(binding.root, this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun dialogConfirmed() {
|
||||
var result = 0
|
||||
for ((key, value) in tabs) {
|
||||
if (view.findViewById<MyAppCompatCheckbox>(value).isChecked) {
|
||||
if (value.isChecked) {
|
||||
result += key
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,32 +5,30 @@ import androidx.appcompat.app.AlertDialog
|
|||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.DialogNewPlaylistBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.getPlaylistIdWithTitle
|
||||
import com.simplemobiletools.musicplayer.models.Playlist
|
||||
import kotlinx.android.synthetic.main.dialog_new_playlist.view.new_playlist_title
|
||||
|
||||
class NewPlaylistDialog(val activity: Activity, var playlist: Playlist? = null, val callback: (playlistId: Int) -> Unit) {
|
||||
var isNewPlaylist = playlist == null
|
||||
private var isNewPlaylist = playlist == null
|
||||
private val binding by activity.viewBinding(DialogNewPlaylistBinding::inflate)
|
||||
|
||||
init {
|
||||
if (playlist == null) {
|
||||
playlist = Playlist(0, "")
|
||||
}
|
||||
|
||||
val view = activity.layoutInflater.inflate(R.layout.dialog_new_playlist, null).apply {
|
||||
new_playlist_title.setText(playlist!!.title)
|
||||
}
|
||||
|
||||
binding.newPlaylistTitle.setText(playlist!!.title)
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(com.simplemobiletools.commons.R.string.ok, null)
|
||||
.setNegativeButton(com.simplemobiletools.commons.R.string.cancel, null)
|
||||
.apply {
|
||||
val dialogTitle = if (isNewPlaylist) R.string.create_new_playlist else R.string.rename_playlist
|
||||
activity.setupDialogStuff(view, this, dialogTitle) { alertDialog ->
|
||||
alertDialog.showKeyboard(view.new_playlist_title)
|
||||
activity.setupDialogStuff(binding.root, this, dialogTitle) { alertDialog ->
|
||||
alertDialog.showKeyboard(binding.newPlaylistTitle)
|
||||
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
||||
val title = view.new_playlist_title.value
|
||||
val title = binding.newPlaylistTitle.value
|
||||
ensureBackgroundThread {
|
||||
val playlistIdWithTitle = activity.getPlaylistIdWithTitle(title)
|
||||
var isPlaylistTitleTaken = isNewPlaylist && playlistIdWithTitle != -1
|
||||
|
@ -39,7 +37,7 @@ class NewPlaylistDialog(val activity: Activity, var playlist: Playlist? = null,
|
|||
}
|
||||
|
||||
if (title.isEmpty()) {
|
||||
activity.toast(R.string.empty_name)
|
||||
activity.toast(com.simplemobiletools.commons.R.string.empty_name)
|
||||
return@ensureBackgroundThread
|
||||
} else if (isPlaylistTitleTaken) {
|
||||
activity.toast(R.string.playlist_name_exists)
|
||||
|
@ -59,7 +57,7 @@ class NewPlaylistDialog(val activity: Activity, var playlist: Playlist? = null,
|
|||
alertDialog.dismiss()
|
||||
callback(eventTypeId)
|
||||
} else {
|
||||
activity.toast(R.string.unknown_error_occurred)
|
||||
activity.toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,21 +3,21 @@ package com.simplemobiletools.musicplayer.dialogs
|
|||
import android.app.Activity
|
||||
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
|
||||
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
||||
import com.simplemobiletools.commons.extensions.viewBinding
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.DialogRemovePlaylistBinding
|
||||
import com.simplemobiletools.musicplayer.models.Playlist
|
||||
import kotlinx.android.synthetic.main.dialog_remove_playlist.view.*
|
||||
|
||||
class RemovePlaylistDialog(val activity: Activity, val playlist: Playlist? = null, val callback: (deleteFiles: Boolean) -> Unit) {
|
||||
init {
|
||||
val view = activity.layoutInflater.inflate(R.layout.dialog_remove_playlist, null).apply {
|
||||
remove_playlist_description.text = getDescriptionText()
|
||||
}
|
||||
private val binding by activity.viewBinding(DialogRemovePlaylistBinding::inflate)
|
||||
|
||||
init {
|
||||
binding.removePlaylistDescription.text = getDescriptionText()
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(R.string.ok) { dialog, which -> callback(view.remove_playlist_checkbox.isChecked) }
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(com.simplemobiletools.commons.R.string.ok) { _, _ -> callback(binding.removePlaylistCheckbox.isChecked) }
|
||||
.setNegativeButton(com.simplemobiletools.commons.R.string.cancel, null)
|
||||
.apply {
|
||||
activity.setupDialogStuff(view, this, R.string.remove_playlist)
|
||||
activity.setupDialogStuff(binding.root, this, R.string.remove_playlist)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +1,27 @@
|
|||
package com.simplemobiletools.musicplayer.dialogs
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RadioGroup
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.simplemobiletools.commons.extensions.getAlertDialogBuilder
|
||||
import com.simplemobiletools.commons.extensions.setupDialogStuff
|
||||
import com.simplemobiletools.commons.extensions.viewBinding
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.DialogSelectPlaylistBinding
|
||||
import com.simplemobiletools.musicplayer.databinding.ItemSelectPlaylistBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.models.Playlist
|
||||
import kotlinx.android.synthetic.main.dialog_select_playlist.view.dialog_select_playlist_linear
|
||||
import kotlinx.android.synthetic.main.dialog_select_playlist.view.dialog_select_playlist_new_radio
|
||||
import kotlinx.android.synthetic.main.item_select_playlist.view.select_playlist_item_radio_button
|
||||
|
||||
class SelectPlaylistDialog(val activity: Activity, val callback: (playlistId: Int) -> Unit) {
|
||||
private var dialog: AlertDialog? = null
|
||||
private val binding by activity.viewBinding(DialogSelectPlaylistBinding::inflate)
|
||||
|
||||
init {
|
||||
val view = activity.layoutInflater.inflate(R.layout.dialog_select_playlist, null)
|
||||
ensureBackgroundThread {
|
||||
val playlists = activity.audioHelper.getAllPlaylists()
|
||||
activity.runOnUiThread {
|
||||
initDialog(playlists, view)
|
||||
initDialog(playlists)
|
||||
|
||||
if (playlists.isEmpty()) {
|
||||
showNewPlaylistDialog()
|
||||
|
@ -31,17 +29,17 @@ class SelectPlaylistDialog(val activity: Activity, val callback: (playlistId: In
|
|||
}
|
||||
}
|
||||
|
||||
view.dialog_select_playlist_new_radio.setOnClickListener {
|
||||
view.dialog_select_playlist_new_radio.isChecked = false
|
||||
binding.dialogSelectPlaylistNewRadio.setOnClickListener {
|
||||
binding.dialogSelectPlaylistNewRadio.isChecked = false
|
||||
showNewPlaylistDialog()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initDialog(playlists: ArrayList<Playlist>, view: View) {
|
||||
private fun initDialog(playlists: ArrayList<Playlist>) {
|
||||
playlists.forEach {
|
||||
activity.layoutInflater.inflate(R.layout.item_select_playlist, null).apply {
|
||||
ItemSelectPlaylistBinding.inflate(activity.layoutInflater).apply {
|
||||
val playlist = it
|
||||
select_playlist_item_radio_button.apply {
|
||||
selectPlaylistItemRadioButton.apply {
|
||||
text = playlist.title
|
||||
isChecked = false
|
||||
id = playlist.id
|
||||
|
@ -52,15 +50,15 @@ class SelectPlaylistDialog(val activity: Activity, val callback: (playlistId: In
|
|||
}
|
||||
}
|
||||
|
||||
view.dialog_select_playlist_linear.addView(
|
||||
this,
|
||||
binding.dialogSelectPlaylistLinear.addView(
|
||||
this.root,
|
||||
RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
activity.getAlertDialogBuilder().apply {
|
||||
activity.setupDialogStuff(view, this) { alertDialog ->
|
||||
activity.setupDialogStuff(binding.root, this) { alertDialog ->
|
||||
dialog = alertDialog
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,28 +4,28 @@ import android.app.Activity
|
|||
import androidx.appcompat.app.AlertDialog
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import kotlinx.android.synthetic.main.dialog_custom_sleep_timer_picker.view.*
|
||||
import com.simplemobiletools.musicplayer.databinding.DialogCustomSleepTimerPickerBinding
|
||||
|
||||
class SleepTimerCustomDialog(val activity: Activity, val callback: (seconds: Int) -> Unit) {
|
||||
private var dialog: AlertDialog? = null
|
||||
private val view = activity.layoutInflater.inflate(R.layout.dialog_custom_sleep_timer_picker, null)
|
||||
private val binding by activity.viewBinding(DialogCustomSleepTimerPickerBinding::inflate)
|
||||
|
||||
init {
|
||||
view.minutes_hint.hint = activity.getString(R.string.minutes_raw).replaceFirstChar { it.uppercaseChar() }
|
||||
binding.minutesHint.hint = activity.getString(com.simplemobiletools.commons.R.string.minutes_raw).replaceFirstChar { it.uppercaseChar() }
|
||||
activity.getAlertDialogBuilder()
|
||||
.setPositiveButton(R.string.ok) { dialog, which -> dialogConfirmed() }
|
||||
.setNegativeButton(R.string.cancel, null)
|
||||
.setPositiveButton(com.simplemobiletools.commons.R.string.ok) { _, _ -> dialogConfirmed() }
|
||||
.setNegativeButton(com.simplemobiletools.commons.R.string.cancel, null)
|
||||
.apply {
|
||||
activity.setupDialogStuff(view, this, R.string.sleep_timer) { alertDialog ->
|
||||
activity.setupDialogStuff(binding.root, this, R.string.sleep_timer) { alertDialog ->
|
||||
dialog = alertDialog
|
||||
alertDialog.showKeyboard(view.minutes)
|
||||
alertDialog.showKeyboard(binding.minutes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun dialogConfirmed() {
|
||||
val value = view.minutes.value
|
||||
val minutes = Integer.valueOf(if (value.isEmpty()) "0" else value)
|
||||
val value = binding.minutes.value
|
||||
val minutes = Integer.valueOf(value.ifEmpty { "0" })
|
||||
callback(minutes * 60)
|
||||
activity.hideKeyboard()
|
||||
dialog?.dismiss()
|
||||
|
|
|
@ -242,16 +242,16 @@ fun Context.loadGlideResource(
|
|||
.load(model)
|
||||
.apply(options)
|
||||
.listener(object : RequestListener<Drawable> {
|
||||
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
|
||||
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>, isFirstResource: Boolean): Boolean {
|
||||
onLoadFailed(e)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onResourceReady(
|
||||
resource: Drawable,
|
||||
model: Any?,
|
||||
target: Target<Drawable>?,
|
||||
dataSource: DataSource?,
|
||||
model: Any,
|
||||
target: Target<Drawable>,
|
||||
dataSource: DataSource,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
onResourceReady(resource)
|
||||
|
@ -266,13 +266,19 @@ fun Context.loadGlideResource(
|
|||
}
|
||||
}
|
||||
|
||||
fun Context.getTrackFromUri(uri: Uri?, callback: (track: Track) -> Unit) {
|
||||
fun Context.getTrackFromUri(uri: Uri?, callback: (track: Track?) -> Unit) {
|
||||
if (uri == null) {
|
||||
callback(null)
|
||||
return
|
||||
}
|
||||
|
||||
ensureBackgroundThread {
|
||||
val path = getRealPathFromURI(uri) ?: return@ensureBackgroundThread
|
||||
val path = getRealPathFromURI(uri)
|
||||
if (path == null) {
|
||||
callback(null)
|
||||
return@ensureBackgroundThread
|
||||
}
|
||||
|
||||
val allTracks = audioHelper.getAllTracks()
|
||||
val track = allTracks.find { it.path == path } ?: RoomHelper(this).getTrackFromPath(path) ?: return@ensureBackgroundThread
|
||||
callback(track)
|
||||
|
@ -281,6 +287,8 @@ fun Context.getTrackFromUri(uri: Uri?, callback: (track: Track) -> Unit) {
|
|||
|
||||
fun Context.isTabVisible(flag: Int) = config.showTabs and flag != 0
|
||||
|
||||
fun Context.getVisibleTabs() = tabsList.filter { isTabVisible(it) }
|
||||
|
||||
fun Context.getPlaybackSetting(repeatMode: @Player.RepeatMode Int): PlaybackSetting {
|
||||
return when (repeatMode) {
|
||||
Player.REPEAT_MODE_OFF -> PlaybackSetting.REPEAT_OFF
|
||||
|
|
|
@ -17,11 +17,11 @@ fun LottieAnimationView.updatePlayPauseIcon(isPlaying: Boolean, color: Int) {
|
|||
playAnimation()
|
||||
}
|
||||
|
||||
addValueCallback(
|
||||
KeyPath("**"),
|
||||
LottieProperty.COLOR_FILTER,
|
||||
{ PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN) }
|
||||
)
|
||||
tag = isPlaying
|
||||
}
|
||||
|
||||
addValueCallback(
|
||||
KeyPath("**"),
|
||||
LottieProperty.COLOR_FILTER
|
||||
) { PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN) }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package com.simplemobiletools.musicplayer.extensions
|
||||
|
||||
import android.view.View
|
||||
import androidx.viewbinding.ViewBinding
|
||||
|
||||
inline fun <T : ViewBinding> View.viewBinding(crossinline bind: (View) -> T) =
|
||||
lazy(LazyThreadSafetyMode.NONE) {
|
||||
bind(this)
|
||||
}
|
|
@ -5,7 +5,6 @@ import android.content.Intent
|
|||
import android.util.AttributeSet
|
||||
import com.google.gson.Gson
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||
import com.simplemobiletools.commons.extensions.areSystemAnimationsEnabled
|
||||
import com.simplemobiletools.commons.extensions.beGoneIf
|
||||
import com.simplemobiletools.commons.extensions.beVisibleIf
|
||||
|
@ -15,21 +14,21 @@ import com.simplemobiletools.musicplayer.R
|
|||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.activities.TracksActivity
|
||||
import com.simplemobiletools.musicplayer.adapters.AlbumsAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.FragmentAlbumsBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.ChangeSortingDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.extensions.mediaScanner
|
||||
import com.simplemobiletools.musicplayer.extensions.viewBinding
|
||||
import com.simplemobiletools.musicplayer.helpers.ALBUM
|
||||
import com.simplemobiletools.musicplayer.helpers.TAB_ALBUMS
|
||||
import com.simplemobiletools.musicplayer.models.Album
|
||||
import com.simplemobiletools.musicplayer.models.sortSafely
|
||||
import kotlinx.android.synthetic.main.fragment_albums.view.albums_fastscroller
|
||||
import kotlinx.android.synthetic.main.fragment_albums.view.albums_list
|
||||
import kotlinx.android.synthetic.main.fragment_albums.view.albums_placeholder
|
||||
|
||||
// Artists -> Albums -> Tracks
|
||||
class AlbumsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) {
|
||||
private var albums = ArrayList<Album>()
|
||||
private val binding by viewBinding(FragmentAlbumsBinding::bind)
|
||||
|
||||
override fun setupFragment(activity: BaseSimpleActivity) {
|
||||
ensureBackgroundThread {
|
||||
|
@ -45,27 +44,27 @@ class AlbumsFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
|
||||
activity.runOnUiThread {
|
||||
val scanning = activity.mediaScanner.isScanning()
|
||||
albums_placeholder.text = if (scanning) {
|
||||
binding.albumsPlaceholder.text = if (scanning) {
|
||||
context.getString(R.string.loading_files)
|
||||
} else {
|
||||
context.getString(R.string.no_items_found)
|
||||
context.getString(com.simplemobiletools.commons.R.string.no_items_found)
|
||||
}
|
||||
albums_placeholder.beVisibleIf(albums.isEmpty())
|
||||
binding.albumsPlaceholder.beVisibleIf(albums.isEmpty())
|
||||
|
||||
val adapter = albums_list.adapter
|
||||
val adapter = binding.albumsList.adapter
|
||||
if (adapter == null) {
|
||||
AlbumsAdapter(activity, albums, albums_list) {
|
||||
AlbumsAdapter(activity, albums, binding.albumsList) {
|
||||
activity.hideKeyboard()
|
||||
Intent(activity, TracksActivity::class.java).apply {
|
||||
putExtra(ALBUM, Gson().toJson(it))
|
||||
activity.startActivity(this)
|
||||
}
|
||||
}.apply {
|
||||
albums_list.adapter = this
|
||||
binding.albumsList.adapter = this
|
||||
}
|
||||
|
||||
if (context.areSystemAnimationsEnabled) {
|
||||
albums_list.scheduleLayoutAnimation()
|
||||
binding.albumsList.scheduleLayoutAnimation()
|
||||
}
|
||||
} else {
|
||||
val oldItems = (adapter as AlbumsAdapter).items
|
||||
|
@ -77,30 +76,33 @@ class AlbumsFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
}
|
||||
|
||||
override fun finishActMode() {
|
||||
(albums_list.adapter as? MyRecyclerViewAdapter)?.finishActMode()
|
||||
getAdapter()?.finishActMode()
|
||||
}
|
||||
|
||||
override fun onSearchQueryChanged(text: String) {
|
||||
val filtered = albums.filter { it.title.contains(text, true) }.toMutableList() as ArrayList<Album>
|
||||
(albums_list.adapter as? AlbumsAdapter)?.updateItems(filtered, text)
|
||||
albums_placeholder.beVisibleIf(filtered.isEmpty())
|
||||
getAdapter()?.updateItems(filtered, text)
|
||||
binding.albumsPlaceholder.beVisibleIf(filtered.isEmpty())
|
||||
}
|
||||
|
||||
override fun onSearchClosed() {
|
||||
(albums_list.adapter as? AlbumsAdapter)?.updateItems(albums)
|
||||
albums_placeholder.beGoneIf(albums.isNotEmpty())
|
||||
getAdapter()?.updateItems(albums)
|
||||
binding.albumsPlaceholder.beGoneIf(albums.isNotEmpty())
|
||||
}
|
||||
|
||||
override fun onSortOpen(activity: SimpleActivity) {
|
||||
ChangeSortingDialog(activity, TAB_ALBUMS) {
|
||||
val adapter = albums_list.adapter as? AlbumsAdapter ?: return@ChangeSortingDialog
|
||||
val adapter = getAdapter() ?: return@ChangeSortingDialog
|
||||
albums.sortSafely(activity.config.albumSorting)
|
||||
adapter.updateItems(albums, forceUpdate = true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setupColors(textColor: Int, adjustedPrimaryColor: Int) {
|
||||
albums_placeholder.setTextColor(textColor)
|
||||
albums_fastscroller.updateColors(adjustedPrimaryColor)
|
||||
binding.albumsPlaceholder.setTextColor(textColor)
|
||||
binding.albumsFastscroller.updateColors(adjustedPrimaryColor)
|
||||
getAdapter()?.updateColors(textColor)
|
||||
}
|
||||
|
||||
private fun getAdapter() = binding.albumsList.adapter as? AlbumsAdapter
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.content.Intent
|
|||
import android.util.AttributeSet
|
||||
import com.google.gson.Gson
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||
import com.simplemobiletools.commons.extensions.areSystemAnimationsEnabled
|
||||
import com.simplemobiletools.commons.extensions.beGoneIf
|
||||
import com.simplemobiletools.commons.extensions.beVisibleIf
|
||||
|
@ -15,21 +14,21 @@ import com.simplemobiletools.musicplayer.R
|
|||
import com.simplemobiletools.musicplayer.activities.AlbumsActivity
|
||||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.adapters.ArtistsAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.FragmentArtistsBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.ChangeSortingDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.extensions.mediaScanner
|
||||
import com.simplemobiletools.musicplayer.extensions.viewBinding
|
||||
import com.simplemobiletools.musicplayer.helpers.ARTIST
|
||||
import com.simplemobiletools.musicplayer.helpers.TAB_ARTISTS
|
||||
import com.simplemobiletools.musicplayer.models.Artist
|
||||
import com.simplemobiletools.musicplayer.models.sortSafely
|
||||
import kotlinx.android.synthetic.main.fragment_artists.view.artists_fastscroller
|
||||
import kotlinx.android.synthetic.main.fragment_artists.view.artists_list
|
||||
import kotlinx.android.synthetic.main.fragment_artists.view.artists_placeholder
|
||||
|
||||
// Artists -> Albums -> Tracks
|
||||
class ArtistsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) {
|
||||
private var artists = ArrayList<Artist>()
|
||||
private val binding by viewBinding(FragmentArtistsBinding::bind)
|
||||
|
||||
override fun setupFragment(activity: BaseSimpleActivity) {
|
||||
ensureBackgroundThread {
|
||||
|
@ -44,27 +43,27 @@ class ArtistsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
|||
artists = cachedArtists
|
||||
activity.runOnUiThread {
|
||||
val scanning = activity.mediaScanner.isScanning()
|
||||
artists_placeholder.text = if (scanning) {
|
||||
binding.artistsPlaceholder.text = if (scanning) {
|
||||
context.getString(R.string.loading_files)
|
||||
} else {
|
||||
context.getString(R.string.no_items_found)
|
||||
context.getString(com.simplemobiletools.commons.R.string.no_items_found)
|
||||
}
|
||||
artists_placeholder.beVisibleIf(artists.isEmpty())
|
||||
binding.artistsPlaceholder.beVisibleIf(artists.isEmpty())
|
||||
|
||||
val adapter = artists_list.adapter
|
||||
val adapter = binding.artistsList.adapter
|
||||
if (adapter == null) {
|
||||
ArtistsAdapter(activity, artists, artists_list) {
|
||||
ArtistsAdapter(activity, artists, binding.artistsList) {
|
||||
activity.hideKeyboard()
|
||||
Intent(activity, AlbumsActivity::class.java).apply {
|
||||
putExtra(ARTIST, Gson().toJson(it as Artist))
|
||||
activity.startActivity(this)
|
||||
}
|
||||
}.apply {
|
||||
artists_list.adapter = this
|
||||
binding.artistsList.adapter = this
|
||||
}
|
||||
|
||||
if (context.areSystemAnimationsEnabled) {
|
||||
artists_list.scheduleLayoutAnimation()
|
||||
binding.artistsList.scheduleLayoutAnimation()
|
||||
}
|
||||
} else {
|
||||
val oldItems = (adapter as ArtistsAdapter).items
|
||||
|
@ -76,30 +75,33 @@ class ArtistsFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
|||
}
|
||||
|
||||
override fun finishActMode() {
|
||||
(artists_list.adapter as? MyRecyclerViewAdapter)?.finishActMode()
|
||||
getAdapter()?.finishActMode()
|
||||
}
|
||||
|
||||
override fun onSearchQueryChanged(text: String) {
|
||||
val filtered = artists.filter { it.title.contains(text, true) }.toMutableList() as ArrayList<Artist>
|
||||
(artists_list.adapter as? ArtistsAdapter)?.updateItems(filtered, text)
|
||||
artists_placeholder.beVisibleIf(filtered.isEmpty())
|
||||
getAdapter()?.updateItems(filtered, text)
|
||||
binding.artistsPlaceholder.beVisibleIf(filtered.isEmpty())
|
||||
}
|
||||
|
||||
override fun onSearchClosed() {
|
||||
(artists_list.adapter as? ArtistsAdapter)?.updateItems(artists)
|
||||
artists_placeholder.beGoneIf(artists.isNotEmpty())
|
||||
getAdapter()?.updateItems(artists)
|
||||
binding.artistsPlaceholder.beGoneIf(artists.isNotEmpty())
|
||||
}
|
||||
|
||||
override fun onSortOpen(activity: SimpleActivity) {
|
||||
ChangeSortingDialog(activity, TAB_ARTISTS) {
|
||||
val adapter = artists_list.adapter as? ArtistsAdapter ?: return@ChangeSortingDialog
|
||||
val adapter = getAdapter() ?: return@ChangeSortingDialog
|
||||
artists.sortSafely(activity.config.artistSorting)
|
||||
adapter.updateItems(artists, forceUpdate = true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setupColors(textColor: Int, adjustedPrimaryColor: Int) {
|
||||
artists_placeholder.setTextColor(textColor)
|
||||
artists_fastscroller.updateColors(adjustedPrimaryColor)
|
||||
binding.artistsPlaceholder.setTextColor(textColor)
|
||||
binding.artistsFastscroller.updateColors(adjustedPrimaryColor)
|
||||
getAdapter()?.updateColors(textColor)
|
||||
}
|
||||
|
||||
private fun getAdapter() = binding.artistsList.adapter as? ArtistsAdapter
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.content.Context
|
|||
import android.content.Intent
|
||||
import android.util.AttributeSet
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
|
@ -12,21 +11,20 @@ import com.simplemobiletools.musicplayer.activities.ExcludedFoldersActivity
|
|||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.activities.TracksActivity
|
||||
import com.simplemobiletools.musicplayer.adapters.FoldersAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.FragmentFoldersBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.ChangeSortingDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.extensions.mediaScanner
|
||||
import com.simplemobiletools.musicplayer.extensions.viewBinding
|
||||
import com.simplemobiletools.musicplayer.helpers.FOLDER
|
||||
import com.simplemobiletools.musicplayer.helpers.TAB_FOLDERS
|
||||
import com.simplemobiletools.musicplayer.models.Folder
|
||||
import com.simplemobiletools.musicplayer.models.sortSafely
|
||||
import kotlinx.android.synthetic.main.fragment_folders.view.folders_fastscroller
|
||||
import kotlinx.android.synthetic.main.fragment_folders.view.folders_list
|
||||
import kotlinx.android.synthetic.main.fragment_folders.view.folders_placeholder
|
||||
import kotlinx.android.synthetic.main.fragment_folders.view.folders_placeholder_2
|
||||
|
||||
class FoldersFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) {
|
||||
private var folders = ArrayList<Folder>()
|
||||
private val binding by viewBinding(FragmentFoldersBinding::bind)
|
||||
|
||||
override fun setupFragment(activity: BaseSimpleActivity) {
|
||||
ensureBackgroundThread {
|
||||
|
@ -34,36 +32,36 @@ class FoldersFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
|||
|
||||
activity.runOnUiThread {
|
||||
val scanning = activity.mediaScanner.isScanning()
|
||||
folders_placeholder.text = if (scanning) {
|
||||
binding.foldersPlaceholder.text = if (scanning) {
|
||||
context.getString(R.string.loading_files)
|
||||
} else {
|
||||
context.getString(R.string.no_items_found)
|
||||
context.getString(com.simplemobiletools.commons.R.string.no_items_found)
|
||||
}
|
||||
folders_placeholder.beVisibleIf(folders.isEmpty())
|
||||
folders_fastscroller.beGoneIf(folders_placeholder.isVisible())
|
||||
folders_placeholder_2.beVisibleIf(folders.isEmpty() && context.config.excludedFolders.isNotEmpty() && !scanning)
|
||||
folders_placeholder_2.underlineText()
|
||||
binding.foldersPlaceholder.beVisibleIf(folders.isEmpty())
|
||||
binding.foldersFastscroller.beGoneIf(binding.foldersPlaceholder.isVisible())
|
||||
binding.foldersPlaceholder2.beVisibleIf(folders.isEmpty() && context.config.excludedFolders.isNotEmpty() && !scanning)
|
||||
binding.foldersPlaceholder2.underlineText()
|
||||
|
||||
folders_placeholder_2.setOnClickListener {
|
||||
binding.foldersPlaceholder2.setOnClickListener {
|
||||
activity.startActivity(Intent(activity, ExcludedFoldersActivity::class.java))
|
||||
}
|
||||
|
||||
this.folders = folders
|
||||
|
||||
val adapter = folders_list.adapter
|
||||
val adapter = binding.foldersList.adapter
|
||||
if (adapter == null) {
|
||||
FoldersAdapter(activity, folders, folders_list) {
|
||||
FoldersAdapter(activity, folders, binding.foldersList) {
|
||||
activity.hideKeyboard()
|
||||
Intent(activity, TracksActivity::class.java).apply {
|
||||
putExtra(FOLDER, (it as Folder).title)
|
||||
activity.startActivity(this)
|
||||
}
|
||||
}.apply {
|
||||
folders_list.adapter = this
|
||||
binding.foldersList.adapter = this
|
||||
}
|
||||
|
||||
if (context.areSystemAnimationsEnabled) {
|
||||
folders_list.scheduleLayoutAnimation()
|
||||
binding.foldersList.scheduleLayoutAnimation()
|
||||
}
|
||||
} else {
|
||||
(adapter as FoldersAdapter).updateItems(folders)
|
||||
|
@ -73,31 +71,34 @@ class FoldersFragment(context: Context, attributeSet: AttributeSet) : MyViewPage
|
|||
}
|
||||
|
||||
override fun finishActMode() {
|
||||
(folders_list.adapter as? MyRecyclerViewAdapter)?.finishActMode()
|
||||
getAdapter()?.finishActMode()
|
||||
}
|
||||
|
||||
override fun onSearchQueryChanged(text: String) {
|
||||
val filtered = folders.filter { it.title.contains(text, true) }.toMutableList() as ArrayList<Folder>
|
||||
(folders_list.adapter as? FoldersAdapter)?.updateItems(filtered, text)
|
||||
folders_placeholder.beVisibleIf(filtered.isEmpty())
|
||||
getAdapter()?.updateItems(filtered, text)
|
||||
binding.foldersPlaceholder.beVisibleIf(filtered.isEmpty())
|
||||
}
|
||||
|
||||
override fun onSearchClosed() {
|
||||
(folders_list.adapter as? FoldersAdapter)?.updateItems(folders)
|
||||
folders_placeholder.beGoneIf(folders.isNotEmpty())
|
||||
getAdapter()?.updateItems(folders)
|
||||
binding.foldersPlaceholder.beGoneIf(folders.isNotEmpty())
|
||||
}
|
||||
|
||||
override fun onSortOpen(activity: SimpleActivity) {
|
||||
ChangeSortingDialog(activity, TAB_FOLDERS) {
|
||||
val adapter = folders_list.adapter as? FoldersAdapter ?: return@ChangeSortingDialog
|
||||
val adapter = getAdapter() ?: return@ChangeSortingDialog
|
||||
folders.sortSafely(activity.config.folderSorting)
|
||||
adapter.updateItems(folders, forceUpdate = true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setupColors(textColor: Int, adjustedPrimaryColor: Int) {
|
||||
folders_placeholder.setTextColor(textColor)
|
||||
folders_fastscroller.updateColors(adjustedPrimaryColor)
|
||||
folders_placeholder_2.setTextColor(adjustedPrimaryColor)
|
||||
binding.foldersPlaceholder.setTextColor(textColor)
|
||||
binding.foldersFastscroller.updateColors(adjustedPrimaryColor)
|
||||
binding.foldersPlaceholder2.setTextColor(adjustedPrimaryColor)
|
||||
getAdapter()?.updateColors(textColor)
|
||||
}
|
||||
|
||||
private fun getAdapter() = binding.foldersList.adapter as? FoldersAdapter
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.content.Intent
|
|||
import android.util.AttributeSet
|
||||
import com.google.gson.Gson
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||
import com.simplemobiletools.commons.extensions.areSystemAnimationsEnabled
|
||||
import com.simplemobiletools.commons.extensions.beGoneIf
|
||||
import com.simplemobiletools.commons.extensions.beVisibleIf
|
||||
|
@ -15,20 +14,20 @@ import com.simplemobiletools.musicplayer.R
|
|||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.activities.TracksActivity
|
||||
import com.simplemobiletools.musicplayer.adapters.GenresAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.FragmentGenresBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.ChangeSortingDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.extensions.mediaScanner
|
||||
import com.simplemobiletools.musicplayer.extensions.viewBinding
|
||||
import com.simplemobiletools.musicplayer.helpers.GENRE
|
||||
import com.simplemobiletools.musicplayer.helpers.TAB_GENRES
|
||||
import com.simplemobiletools.musicplayer.models.Genre
|
||||
import com.simplemobiletools.musicplayer.models.sortSafely
|
||||
import kotlinx.android.synthetic.main.fragment_genres.view.genres_fastscroller
|
||||
import kotlinx.android.synthetic.main.fragment_genres.view.genres_list
|
||||
import kotlinx.android.synthetic.main.fragment_genres.view.genres_placeholder
|
||||
|
||||
class GenresFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) {
|
||||
private var genres = ArrayList<Genre>()
|
||||
private val binding by viewBinding(FragmentGenresBinding::bind)
|
||||
|
||||
override fun setupFragment(activity: BaseSimpleActivity) {
|
||||
ensureBackgroundThread {
|
||||
|
@ -43,27 +42,28 @@ class GenresFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
genres = cachedGenres
|
||||
activity.runOnUiThread {
|
||||
val scanning = activity.mediaScanner.isScanning()
|
||||
genres_placeholder.text = if (scanning) {
|
||||
binding.genresPlaceholder.text = if (scanning) {
|
||||
context.getString(R.string.loading_files)
|
||||
} else {
|
||||
context.getString(R.string.no_items_found)
|
||||
context.getString(com.simplemobiletools.commons.R.string.no_items_found)
|
||||
}
|
||||
genres_placeholder.beVisibleIf(genres.isEmpty())
|
||||
|
||||
val adapter = genres_list.adapter
|
||||
binding.genresPlaceholder.beVisibleIf(genres.isEmpty())
|
||||
|
||||
val adapter = binding.genresList.adapter
|
||||
if (adapter == null) {
|
||||
GenresAdapter(activity, genres, genres_list) {
|
||||
GenresAdapter(activity, genres, binding.genresList) {
|
||||
activity.hideKeyboard()
|
||||
Intent(activity, TracksActivity::class.java).apply {
|
||||
putExtra(GENRE, Gson().toJson(it as Genre))
|
||||
activity.startActivity(this)
|
||||
}
|
||||
}.apply {
|
||||
genres_list.adapter = this
|
||||
binding.genresList.adapter = this
|
||||
}
|
||||
|
||||
if (context.areSystemAnimationsEnabled) {
|
||||
genres_list.scheduleLayoutAnimation()
|
||||
binding.genresList.scheduleLayoutAnimation()
|
||||
}
|
||||
} else {
|
||||
val oldItems = (adapter as GenresAdapter).items
|
||||
|
@ -75,30 +75,33 @@ class GenresFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
}
|
||||
|
||||
override fun finishActMode() {
|
||||
(genres_list.adapter as? MyRecyclerViewAdapter)?.finishActMode()
|
||||
getAdapter()?.finishActMode()
|
||||
}
|
||||
|
||||
override fun onSearchQueryChanged(text: String) {
|
||||
val filtered = genres.filter { it.title.contains(text, true) }.toMutableList() as ArrayList<Genre>
|
||||
(genres_list.adapter as? GenresAdapter)?.updateItems(filtered, text)
|
||||
genres_placeholder.beVisibleIf(filtered.isEmpty())
|
||||
getAdapter()?.updateItems(filtered, text)
|
||||
binding.genresPlaceholder.beVisibleIf(filtered.isEmpty())
|
||||
}
|
||||
|
||||
override fun onSearchClosed() {
|
||||
(genres_list.adapter as? GenresAdapter)?.updateItems(genres)
|
||||
genres_placeholder.beGoneIf(genres.isNotEmpty())
|
||||
getAdapter()?.updateItems(genres)
|
||||
binding.genresPlaceholder.beGoneIf(genres.isNotEmpty())
|
||||
}
|
||||
|
||||
override fun onSortOpen(activity: SimpleActivity) {
|
||||
ChangeSortingDialog(activity, TAB_GENRES) {
|
||||
val adapter = genres_list.adapter as? GenresAdapter ?: return@ChangeSortingDialog
|
||||
val adapter = getAdapter() ?: return@ChangeSortingDialog
|
||||
genres.sortSafely(activity.config.genreSorting)
|
||||
adapter.updateItems(genres, forceUpdate = true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setupColors(textColor: Int, adjustedPrimaryColor: Int) {
|
||||
genres_placeholder.setTextColor(textColor)
|
||||
genres_fastscroller.updateColors(adjustedPrimaryColor)
|
||||
binding.genresPlaceholder.setTextColor(textColor)
|
||||
binding.genresFastscroller.updateColors(adjustedPrimaryColor)
|
||||
getAdapter()?.updateColors(textColor)
|
||||
}
|
||||
|
||||
private fun getAdapter() = binding.genresList.adapter as? GenresAdapter
|
||||
}
|
||||
|
|
|
@ -5,15 +5,16 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.views.MySeekBar
|
||||
import com.simplemobiletools.commons.views.MyTextView
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.databinding.FragmentPlaybackSpeedBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.helpers.Config
|
||||
import com.simplemobiletools.musicplayer.interfaces.PlaybackSpeedListener
|
||||
import kotlinx.android.synthetic.main.fragment_playback_speed.view.*
|
||||
|
||||
class PlaybackSpeedFragment : BottomSheetDialogFragment() {
|
||||
private val MIN_PLAYBACK_SPEED = 0.25f
|
||||
|
@ -30,24 +31,25 @@ class PlaybackSpeedFragment : BottomSheetDialogFragment() {
|
|||
setStyle(STYLE_NORMAL, R.style.CustomBottomSheetDialogTheme)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
val config = requireContext().config
|
||||
val view = inflater.inflate(R.layout.fragment_playback_speed, container, false)
|
||||
val background = requireContext().resources.getDrawable(R.drawable.bottom_sheet_bg, requireContext().theme)
|
||||
(background as LayerDrawable).findDrawableByLayerId(R.id.bottom_sheet_background).applyColorFilter(requireContext().getProperBackgroundColor())
|
||||
val binding = FragmentPlaybackSpeedBinding.inflate(inflater, container, false)
|
||||
val background = ResourcesCompat.getDrawable(resources, com.simplemobiletools.commons.R.drawable.bottom_sheet_bg, requireContext().theme)
|
||||
(background as LayerDrawable).findDrawableByLayerId(com.simplemobiletools.commons.R.id.bottom_sheet_background)
|
||||
.applyColorFilter(requireContext().getProperBackgroundColor())
|
||||
|
||||
view.apply {
|
||||
seekBar = playback_speed_seekbar
|
||||
setBackgroundDrawable(background)
|
||||
requireContext().updateTextColors(playback_speed_holder)
|
||||
playback_speed_slow.applyColorFilter(requireContext().getProperTextColor())
|
||||
playback_speed_fast.applyColorFilter(requireContext().getProperTextColor())
|
||||
playback_speed_slow.setOnClickListener { reduceSpeed() }
|
||||
playback_speed_fast.setOnClickListener { increaseSpeed() }
|
||||
initSeekbar(playback_speed_seekbar, playback_speed_label, config)
|
||||
binding.apply {
|
||||
seekBar = playbackSpeedSeekbar
|
||||
root.setBackgroundDrawable(background)
|
||||
requireContext().updateTextColors(playbackSpeedHolder)
|
||||
playbackSpeedSlow.applyColorFilter(requireContext().getProperTextColor())
|
||||
playbackSpeedFast.applyColorFilter(requireContext().getProperTextColor())
|
||||
playbackSpeedSlow.setOnClickListener { reduceSpeed() }
|
||||
playbackSpeedFast.setOnClickListener { increaseSpeed() }
|
||||
initSeekbar(playbackSpeedSeekbar, playbackSpeedLabel, config)
|
||||
}
|
||||
|
||||
return view
|
||||
return binding.root
|
||||
}
|
||||
|
||||
private fun initSeekbar(seekbar: MySeekBar, speedLabel: MyTextView, config: Config) {
|
||||
|
@ -87,11 +89,13 @@ class PlaybackSpeedFragment : BottomSheetDialogFragment() {
|
|||
val lowerProgress = (1 - MIN_PLAYBACK_SPEED) * lowerProgressPercent + MIN_PLAYBACK_SPEED
|
||||
lowerProgress
|
||||
}
|
||||
|
||||
progress > HALF_PROGRESS -> {
|
||||
val upperProgressPercent = progress / HALF_PROGRESS.toFloat() - 1
|
||||
val upperDiff = MAX_PLAYBACK_SPEED - 1
|
||||
upperDiff * upperProgressPercent + 1
|
||||
}
|
||||
|
||||
else -> 1f
|
||||
}
|
||||
playbackSpeed = Math.min(Math.max(playbackSpeed, MIN_PLAYBACK_SPEED), MAX_PLAYBACK_SPEED)
|
||||
|
|
|
@ -5,35 +5,33 @@ import android.content.Intent
|
|||
import android.util.AttributeSet
|
||||
import com.google.gson.Gson
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.activities.TracksActivity
|
||||
import com.simplemobiletools.musicplayer.adapters.PlaylistsAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.FragmentPlaylistsBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.ChangeSortingDialog
|
||||
import com.simplemobiletools.musicplayer.dialogs.NewPlaylistDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.extensions.mediaScanner
|
||||
import com.simplemobiletools.musicplayer.extensions.viewBinding
|
||||
import com.simplemobiletools.musicplayer.helpers.PLAYLIST
|
||||
import com.simplemobiletools.musicplayer.helpers.TAB_PLAYLISTS
|
||||
import com.simplemobiletools.musicplayer.models.Events
|
||||
import com.simplemobiletools.musicplayer.models.Playlist
|
||||
import com.simplemobiletools.musicplayer.models.sortSafely
|
||||
import kotlinx.android.synthetic.main.fragment_playlists.view.playlists_fastscroller
|
||||
import kotlinx.android.synthetic.main.fragment_playlists.view.playlists_list
|
||||
import kotlinx.android.synthetic.main.fragment_playlists.view.playlists_placeholder
|
||||
import kotlinx.android.synthetic.main.fragment_playlists.view.playlists_placeholder_2
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
|
||||
class PlaylistsFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) {
|
||||
private var playlists = ArrayList<Playlist>()
|
||||
private val binding by viewBinding(FragmentPlaylistsBinding::bind)
|
||||
|
||||
override fun setupFragment(activity: BaseSimpleActivity) {
|
||||
playlists_placeholder_2.underlineText()
|
||||
playlists_placeholder_2.setOnClickListener {
|
||||
binding.playlistsPlaceholder2.underlineText()
|
||||
binding.playlistsPlaceholder2.setOnClickListener {
|
||||
NewPlaylistDialog(activity) {
|
||||
EventBus.getDefault().post(Events.PlaylistsUpdated())
|
||||
}
|
||||
|
@ -50,28 +48,28 @@ class PlaylistsFragment(context: Context, attributeSet: AttributeSet) : MyViewPa
|
|||
|
||||
activity.runOnUiThread {
|
||||
val scanning = activity.mediaScanner.isScanning()
|
||||
playlists_placeholder.text = if (scanning) {
|
||||
binding.playlistsPlaceholder.text = if (scanning) {
|
||||
context.getString(R.string.loading_files)
|
||||
} else {
|
||||
context.getString(R.string.no_items_found)
|
||||
context.getString(com.simplemobiletools.commons.R.string.no_items_found)
|
||||
}
|
||||
playlists_placeholder.beVisibleIf(playlists.isEmpty())
|
||||
playlists_placeholder_2.beVisibleIf(playlists.isEmpty() && !scanning)
|
||||
binding.playlistsPlaceholder.beVisibleIf(playlists.isEmpty())
|
||||
binding.playlistsPlaceholder2.beVisibleIf(playlists.isEmpty() && !scanning)
|
||||
|
||||
val adapter = playlists_list.adapter
|
||||
val adapter = binding.playlistsList.adapter
|
||||
if (adapter == null) {
|
||||
PlaylistsAdapter(activity, playlists, playlists_list) {
|
||||
PlaylistsAdapter(activity, playlists, binding.playlistsList) {
|
||||
activity.hideKeyboard()
|
||||
Intent(activity, TracksActivity::class.java).apply {
|
||||
putExtra(PLAYLIST, Gson().toJson(it))
|
||||
activity.startActivity(this)
|
||||
}
|
||||
}.apply {
|
||||
playlists_list.adapter = this
|
||||
binding.playlistsList.adapter = this
|
||||
}
|
||||
|
||||
if (context.areSystemAnimationsEnabled) {
|
||||
playlists_list.scheduleLayoutAnimation()
|
||||
binding.playlistsList.scheduleLayoutAnimation()
|
||||
}
|
||||
} else {
|
||||
(adapter as PlaylistsAdapter).updateItems(playlists)
|
||||
|
@ -81,33 +79,36 @@ class PlaylistsFragment(context: Context, attributeSet: AttributeSet) : MyViewPa
|
|||
}
|
||||
|
||||
override fun finishActMode() {
|
||||
(playlists_list.adapter as? MyRecyclerViewAdapter)?.finishActMode()
|
||||
getAdapter()?.finishActMode()
|
||||
}
|
||||
|
||||
override fun onSearchQueryChanged(text: String) {
|
||||
val filtered = playlists.filter { it.title.contains(text, true) }.toMutableList() as ArrayList<Playlist>
|
||||
(playlists_list.adapter as? PlaylistsAdapter)?.updateItems(filtered, text)
|
||||
playlists_placeholder.beVisibleIf(filtered.isEmpty())
|
||||
playlists_placeholder_2.beVisibleIf(filtered.isEmpty())
|
||||
getAdapter()?.updateItems(filtered, text)
|
||||
binding.playlistsPlaceholder.beVisibleIf(filtered.isEmpty())
|
||||
binding.playlistsPlaceholder2.beVisibleIf(filtered.isEmpty())
|
||||
}
|
||||
|
||||
override fun onSearchClosed() {
|
||||
(playlists_list.adapter as? PlaylistsAdapter)?.updateItems(playlists)
|
||||
playlists_placeholder.beGoneIf(playlists.isNotEmpty())
|
||||
playlists_placeholder_2.beGoneIf(playlists.isNotEmpty())
|
||||
getAdapter()?.updateItems(playlists)
|
||||
binding.playlistsPlaceholder.beGoneIf(playlists.isNotEmpty())
|
||||
binding.playlistsPlaceholder2.beGoneIf(playlists.isNotEmpty())
|
||||
}
|
||||
|
||||
override fun onSortOpen(activity: SimpleActivity) {
|
||||
ChangeSortingDialog(activity, TAB_PLAYLISTS) {
|
||||
val adapter = playlists_list.adapter as? PlaylistsAdapter ?: return@ChangeSortingDialog
|
||||
val adapter = getAdapter() ?: return@ChangeSortingDialog
|
||||
playlists.sortSafely(activity.config.playlistSorting)
|
||||
adapter.updateItems(playlists, forceUpdate = true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setupColors(textColor: Int, adjustedPrimaryColor: Int) {
|
||||
playlists_placeholder.setTextColor(textColor)
|
||||
playlists_placeholder_2.setTextColor(adjustedPrimaryColor)
|
||||
playlists_fastscroller.updateColors(adjustedPrimaryColor)
|
||||
binding.playlistsPlaceholder.setTextColor(textColor)
|
||||
binding.playlistsPlaceholder2.setTextColor(adjustedPrimaryColor)
|
||||
binding.playlistsFastscroller.updateColors(adjustedPrimaryColor)
|
||||
getAdapter()?.updateColors(textColor)
|
||||
}
|
||||
|
||||
private fun getAdapter() = binding.playlistsList.adapter as? PlaylistsAdapter
|
||||
}
|
||||
|
|
|
@ -4,27 +4,31 @@ import android.app.Activity
|
|||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
||||
import com.simplemobiletools.commons.adapters.MyRecyclerViewAdapter
|
||||
import com.simplemobiletools.commons.dialogs.PermissionRequiredDialog
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.commons.extensions.areSystemAnimationsEnabled
|
||||
import com.simplemobiletools.commons.extensions.beGoneIf
|
||||
import com.simplemobiletools.commons.extensions.beVisibleIf
|
||||
import com.simplemobiletools.commons.extensions.getParentPath
|
||||
import com.simplemobiletools.commons.extensions.hideKeyboard
|
||||
import com.simplemobiletools.commons.extensions.openNotificationSettings
|
||||
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.activities.SimpleActivity
|
||||
import com.simplemobiletools.musicplayer.adapters.TracksAdapter
|
||||
import com.simplemobiletools.musicplayer.databinding.FragmentTracksBinding
|
||||
import com.simplemobiletools.musicplayer.dialogs.ChangeSortingDialog
|
||||
import com.simplemobiletools.musicplayer.extensions.audioHelper
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.extensions.mediaScanner
|
||||
import com.simplemobiletools.musicplayer.extensions.viewBinding
|
||||
import com.simplemobiletools.musicplayer.helpers.TAB_TRACKS
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import com.simplemobiletools.musicplayer.models.sortSafely
|
||||
import kotlinx.android.synthetic.main.fragment_tracks.view.tracks_fastscroller
|
||||
import kotlinx.android.synthetic.main.fragment_tracks.view.tracks_list
|
||||
import kotlinx.android.synthetic.main.fragment_tracks.view.tracks_placeholder
|
||||
|
||||
// Artists -> Albums -> Tracks
|
||||
class TracksFragment(context: Context, attributeSet: AttributeSet) : MyViewPagerFragment(context, attributeSet) {
|
||||
private var tracks = ArrayList<Track>()
|
||||
private val binding by viewBinding(FragmentTracksBinding::bind)
|
||||
|
||||
override fun setupFragment(activity: BaseSimpleActivity) {
|
||||
ensureBackgroundThread {
|
||||
|
@ -37,15 +41,15 @@ class TracksFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
|
||||
activity.runOnUiThread {
|
||||
val scanning = activity.mediaScanner.isScanning()
|
||||
tracks_placeholder.text = if (scanning) {
|
||||
binding.tracksPlaceholder.text = if (scanning) {
|
||||
context.getString(R.string.loading_files)
|
||||
} else {
|
||||
context.getString(R.string.no_items_found)
|
||||
context.getString(com.simplemobiletools.commons.R.string.no_items_found)
|
||||
}
|
||||
tracks_placeholder.beVisibleIf(tracks.isEmpty())
|
||||
val adapter = tracks_list.adapter
|
||||
binding.tracksPlaceholder.beVisibleIf(tracks.isEmpty())
|
||||
val adapter = binding.tracksList.adapter
|
||||
if (adapter == null) {
|
||||
TracksAdapter(activity = activity, recyclerView = tracks_list, sourceType = TracksAdapter.TYPE_TRACKS, items = tracks) {
|
||||
TracksAdapter(activity = activity, recyclerView = binding.tracksList, sourceType = TracksAdapter.TYPE_TRACKS, items = tracks) {
|
||||
activity.hideKeyboard()
|
||||
activity.handleNotificationPermission { granted ->
|
||||
if (granted) {
|
||||
|
@ -53,16 +57,20 @@ class TracksFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
prepareAndPlay(tracks, startIndex)
|
||||
} else {
|
||||
if (context is Activity) {
|
||||
PermissionRequiredDialog(activity, R.string.allow_notifications_music_player, { activity.openNotificationSettings() })
|
||||
PermissionRequiredDialog(
|
||||
activity,
|
||||
com.simplemobiletools.commons.R.string.allow_notifications_music_player,
|
||||
{ activity.openNotificationSettings() }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.apply {
|
||||
tracks_list.adapter = this
|
||||
binding.tracksList.adapter = this
|
||||
}
|
||||
|
||||
if (context.areSystemAnimationsEnabled) {
|
||||
tracks_list.scheduleLayoutAnimation()
|
||||
binding.tracksList.scheduleLayoutAnimation()
|
||||
}
|
||||
} else {
|
||||
(adapter as TracksAdapter).updateItems(tracks)
|
||||
|
@ -72,32 +80,35 @@ class TracksFragment(context: Context, attributeSet: AttributeSet) : MyViewPager
|
|||
}
|
||||
|
||||
override fun finishActMode() {
|
||||
(tracks_list.adapter as? MyRecyclerViewAdapter)?.finishActMode()
|
||||
getAdapter()?.finishActMode()
|
||||
}
|
||||
|
||||
override fun onSearchQueryChanged(text: String) {
|
||||
val filtered = tracks.filter {
|
||||
it.title.contains(text, true) || ("${it.artist} - ${it.album}").contains(text, true)
|
||||
}.toMutableList() as ArrayList<Track>
|
||||
(tracks_list.adapter as? TracksAdapter)?.updateItems(filtered, text)
|
||||
tracks_placeholder.beVisibleIf(filtered.isEmpty())
|
||||
getAdapter()?.updateItems(filtered, text)
|
||||
binding.tracksPlaceholder.beVisibleIf(filtered.isEmpty())
|
||||
}
|
||||
|
||||
override fun onSearchClosed() {
|
||||
(tracks_list.adapter as? TracksAdapter)?.updateItems(tracks)
|
||||
tracks_placeholder.beGoneIf(tracks.isNotEmpty())
|
||||
getAdapter()?.updateItems(tracks)
|
||||
binding.tracksPlaceholder.beGoneIf(tracks.isNotEmpty())
|
||||
}
|
||||
|
||||
override fun onSortOpen(activity: SimpleActivity) {
|
||||
ChangeSortingDialog(activity, TAB_TRACKS) {
|
||||
val adapter = tracks_list.adapter as? TracksAdapter ?: return@ChangeSortingDialog
|
||||
val adapter = getAdapter() ?: return@ChangeSortingDialog
|
||||
tracks.sortSafely(activity.config.trackSorting)
|
||||
adapter.updateItems(tracks, forceUpdate = true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun setupColors(textColor: Int, adjustedPrimaryColor: Int) {
|
||||
tracks_placeholder.setTextColor(textColor)
|
||||
tracks_fastscroller.updateColors(adjustedPrimaryColor)
|
||||
binding.tracksPlaceholder.setTextColor(textColor)
|
||||
binding.tracksFastscroller.updateColors(adjustedPrimaryColor)
|
||||
getAdapter()?.updateColors(textColor)
|
||||
}
|
||||
|
||||
private fun getAdapter() = binding.tracksList.adapter as? TracksAdapter
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import com.simplemobiletools.commons.activities.BaseSimpleActivity
|
|||
import com.simplemobiletools.commons.extensions.showErrorToast
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import com.simplemobiletools.commons.extensions.writeLn
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.models.Track
|
||||
import java.io.OutputStream
|
||||
|
||||
|
@ -26,7 +25,7 @@ class M3uExporter(val activity: BaseSimpleActivity) {
|
|||
return
|
||||
}
|
||||
|
||||
activity.toast(R.string.exporting)
|
||||
activity.toast(com.simplemobiletools.commons.R.string.exporting)
|
||||
|
||||
try {
|
||||
outputStream.bufferedWriter().use { out ->
|
||||
|
|
|
@ -105,7 +105,7 @@ class MyWidgetProvider : AppWidgetProvider() {
|
|||
}
|
||||
|
||||
private fun updatePlayPauseButton(context: Context, views: RemoteViews, isPlaying: Boolean) {
|
||||
val drawableId = if (isPlaying) R.drawable.ic_pause_vector else R.drawable.ic_play_vector
|
||||
val drawableId = if (isPlaying) com.simplemobiletools.commons.R.drawable.ic_pause_vector else com.simplemobiletools.commons.R.drawable.ic_play_vector
|
||||
val widgetTextColor = context.config.widgetTextColor
|
||||
val icon = context.resources.getColoredBitmap(drawableId, widgetTextColor)
|
||||
views.setImageViewBitmap(R.id.play_pause_btn, icon)
|
||||
|
@ -120,8 +120,14 @@ class MyWidgetProvider : AppWidgetProvider() {
|
|||
applyColorFilter(R.id.widget_background, widgetBgColor)
|
||||
setTextColor(R.id.song_info_title, widgetTextColor)
|
||||
setTextColor(R.id.song_info_artist, widgetTextColor)
|
||||
setImageViewBitmap(R.id.previous_btn, context.resources.getColoredBitmap(R.drawable.ic_previous_vector, widgetTextColor))
|
||||
setImageViewBitmap(R.id.next_btn, context.resources.getColoredBitmap(R.drawable.ic_next_vector, widgetTextColor))
|
||||
setImageViewBitmap(
|
||||
R.id.previous_btn,
|
||||
context.resources.getColoredBitmap(
|
||||
com.simplemobiletools.commons.R.drawable.ic_previous_vector,
|
||||
widgetTextColor
|
||||
)
|
||||
)
|
||||
setImageViewBitmap(R.id.next_btn, context.resources.getColoredBitmap(com.simplemobiletools.commons.R.drawable.ic_next_vector, widgetTextColor))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ class NotificationHelper(private val context: Context) {
|
|||
|
||||
fun createNoPermissionNotification(): Notification {
|
||||
return NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
|
||||
.setContentTitle(context.getString(R.string.no_storage_permissions))
|
||||
.setContentTitle(context.getString(com.simplemobiletools.commons.R.string.no_storage_permissions))
|
||||
.setSmallIcon(R.drawable.ic_headset_small)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
|
||||
.setPriority(NotificationCompat.PRIORITY_MAX)
|
||||
|
@ -34,7 +34,7 @@ class NotificationHelper(private val context: Context) {
|
|||
}
|
||||
|
||||
fun createMediaScannerNotification(contentText: String, progress: Int, max: Int): Notification {
|
||||
val title = context.getString(R.string.scanning)
|
||||
val title = context.getString(com.simplemobiletools.commons.R.string.scanning)
|
||||
return NotificationCompat.Builder(context, NOTIFICATION_CHANNEL)
|
||||
.setContentTitle(title)
|
||||
.setSmallIcon(R.drawable.ic_headset_small)
|
||||
|
@ -52,7 +52,6 @@ class NotificationHelper(private val context: Context) {
|
|||
}.build()
|
||||
}
|
||||
|
||||
|
||||
fun notify(id: Int, notification: Notification) = notificationManager.notify(id, notification)
|
||||
|
||||
fun cancel(id: Int) = notificationManager.cancel(id)
|
||||
|
|
|
@ -71,7 +71,7 @@ class SimpleMediaScanner(private val context: Application) {
|
|||
} catch (ignored: Exception) {
|
||||
} finally {
|
||||
if (showProgress && newTracks.isEmpty()) {
|
||||
context.toast(R.string.no_items_found)
|
||||
context.toast(com.simplemobiletools.commons.R.string.no_items_found)
|
||||
}
|
||||
|
||||
newTracks.clear()
|
||||
|
|
|
@ -21,7 +21,6 @@ data class Folder(val title: String, val trackCount: Int, val path: String) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fun getBubbleText(sorting: Int) = when {
|
||||
sorting and PLAYER_SORT_BY_TITLE != 0 -> title
|
||||
else -> trackCount.toString()
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.content.Context
|
|||
import android.os.Bundle
|
||||
import androidx.media3.session.CommandButton
|
||||
import androidx.media3.session.SessionCommand
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.helpers.PATH
|
||||
|
||||
/**
|
||||
|
@ -32,9 +31,9 @@ internal val customCommands = CustomCommands.values().map { it.sessionCommand }
|
|||
internal fun Context.getCustomLayout(): List<CommandButton> {
|
||||
return listOf(
|
||||
CommandButton.Builder()
|
||||
.setDisplayName(getString(R.string.close))
|
||||
.setDisplayName(getString(com.simplemobiletools.commons.R.string.close))
|
||||
.setSessionCommand(CustomCommands.CLOSE_PLAYER.sessionCommand)
|
||||
.setIconResId(R.drawable.ic_cross_vector)
|
||||
.setIconResId(com.simplemobiletools.commons.R.drawable.ic_cross_vector)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ import androidx.media3.common.util.UnstableApi
|
|||
import androidx.media3.session.*
|
||||
import com.simplemobiletools.commons.extensions.hasPermission
|
||||
import com.simplemobiletools.commons.extensions.showErrorToast
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
import com.simplemobiletools.musicplayer.helpers.NotificationHelper
|
||||
import com.simplemobiletools.musicplayer.helpers.getPermissionToRequest
|
||||
|
@ -92,7 +91,7 @@ class PlaybackService : MediaLibraryService(), MediaSessionService.Listener {
|
|||
* background.
|
||||
*/
|
||||
override fun onForegroundServiceStartNotAllowedException() {
|
||||
showErrorToast(getString(R.string.unknown_error_occurred))
|
||||
showErrorToast(getString(com.simplemobiletools.commons.R.string.unknown_error_occurred))
|
||||
// todo: show a notification instead.
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ import androidx.media3.common.util.UnstableApi
|
|||
import com.google.gson.Gson
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.helpers.EQUALIZER_PRESET_CUSTOM
|
||||
import com.simplemobiletools.musicplayer.playback.player.SimpleMusicPlayer
|
||||
|
@ -39,7 +38,7 @@ object SimpleEqualizer {
|
|||
}
|
||||
}
|
||||
} catch (ignored: Exception) {
|
||||
context.toast(R.string.unknown_error_occurred)
|
||||
context.toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -155,7 +155,11 @@ internal class MediaItemProvider(private val context: Context) {
|
|||
state = STATE_INITIALIZING
|
||||
|
||||
ensureBackgroundThread {
|
||||
val root = buildMediaItem(title = context.getString(R.string.root), mediaId = SMP_ROOT_ID, mediaType = MediaMetadata.MEDIA_TYPE_FOLDER_MIXED)
|
||||
val root = buildMediaItem(
|
||||
title = context.getString(com.simplemobiletools.commons.R.string.root),
|
||||
mediaId = SMP_ROOT_ID,
|
||||
mediaType = MediaMetadata.MEDIA_TYPE_FOLDER_MIXED
|
||||
)
|
||||
val rootChildren = RootCategories.buildRootChildren(context)
|
||||
addNodeAndChildren(item = root, children = rootChildren)
|
||||
|
||||
|
@ -233,7 +237,7 @@ internal class MediaItemProvider(private val context: Context) {
|
|||
private enum class RootCategories(@StringRes val titleRes: Int, @DrawableRes val drawableRes: Int, val mediaId: String, val mediaType: @MediaType Int) {
|
||||
PLAYLISTS(R.string.playlists, R.drawable.ic_playlist_vector, SMP_PLAYLISTS_ROOT_ID, MediaMetadata.MEDIA_TYPE_FOLDER_PLAYLISTS),
|
||||
FOLDERS(R.string.folders, R.drawable.ic_folders_vector, SMP_FOLDERS_ROOT_ID, MediaMetadata.MEDIA_TYPE_FOLDER_PLAYLISTS),
|
||||
ARTISTS(R.string.artists, R.drawable.ic_person_vector, SMP_ARTISTS_ROOT_ID, MediaMetadata.MEDIA_TYPE_FOLDER_ARTISTS),
|
||||
ARTISTS(R.string.artists, com.simplemobiletools.commons.R.drawable.ic_person_vector, SMP_ARTISTS_ROOT_ID, MediaMetadata.MEDIA_TYPE_FOLDER_ARTISTS),
|
||||
ALBUMS(R.string.albums, R.drawable.ic_album_vector, SMP_ALBUMS_ROOT_ID, MediaMetadata.MEDIA_TYPE_FOLDER_ALBUMS),
|
||||
TRACKS(R.string.tracks, R.drawable.ic_music_note_vector, SMP_TRACKS_ROOT_ID, MediaMetadata.MEDIA_TYPE_PLAYLIST),
|
||||
GENRES(R.string.genres, R.drawable.ic_genre_vector, SMP_GENRES_ROOT_ID, MediaMetadata.MEDIA_TYPE_FOLDER_GENRES);
|
||||
|
|
|
@ -6,7 +6,6 @@ import androidx.media3.common.PlaybackException
|
|||
import androidx.media3.common.Player
|
||||
import androidx.media3.common.util.UnstableApi
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.extensions.config
|
||||
import com.simplemobiletools.musicplayer.extensions.getPlaybackSetting
|
||||
import com.simplemobiletools.musicplayer.helpers.PlaybackSetting
|
||||
|
@ -15,7 +14,7 @@ import com.simplemobiletools.musicplayer.playback.PlaybackService
|
|||
@UnstableApi
|
||||
internal fun PlaybackService.getPlayerListener() = object : Player.Listener {
|
||||
|
||||
override fun onPlayerError(error: PlaybackException) = toast(R.string.unknown_error_occurred, Toast.LENGTH_LONG)
|
||||
override fun onPlayerError(error: PlaybackException) = toast(com.simplemobiletools.commons.R.string.unknown_error_occurred, Toast.LENGTH_LONG)
|
||||
|
||||
override fun onEvents(player: Player, events: Player.Events) {
|
||||
if (
|
||||
|
@ -38,15 +37,17 @@ internal fun PlaybackService.getPlayerListener() = object : Player.Listener {
|
|||
withPlayer {
|
||||
if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT) {
|
||||
if (config.playbackSetting == PlaybackSetting.STOP_AFTER_CURRENT_TRACK) {
|
||||
pause()
|
||||
seekTo(0)
|
||||
pause()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRepeatModeChanged(repeatMode: Int) {
|
||||
config.playbackSetting = getPlaybackSetting(repeatMode)
|
||||
if (config.playbackSetting != PlaybackSetting.STOP_AFTER_CURRENT_TRACK) {
|
||||
config.playbackSetting = getPlaybackSetting(repeatMode)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onShuffleModeEnabledChanged(shuffleModeEnabled: Boolean) {
|
||||
|
|
|
@ -14,24 +14,21 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
|||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.simplemobiletools.commons.extensions.*
|
||||
import com.simplemobiletools.musicplayer.R
|
||||
import com.simplemobiletools.musicplayer.extensions.ensureActivityNotDestroyed
|
||||
import com.simplemobiletools.musicplayer.extensions.getTrackCoverArt
|
||||
import com.simplemobiletools.musicplayer.extensions.toTrack
|
||||
import com.simplemobiletools.musicplayer.extensions.updatePlayPauseIcon
|
||||
import kotlinx.android.synthetic.main.view_current_track_bar.view.current_track_label
|
||||
import kotlinx.android.synthetic.main.view_current_track_bar.view.current_track_play_pause
|
||||
import com.simplemobiletools.musicplayer.databinding.ViewCurrentTrackBarBinding
|
||||
import com.simplemobiletools.musicplayer.extensions.*
|
||||
|
||||
class CurrentTrackBar(context: Context, attributeSet: AttributeSet) : RelativeLayout(context, attributeSet) {
|
||||
private val binding by viewBinding(ViewCurrentTrackBarBinding::bind)
|
||||
|
||||
fun initialize(togglePlayback: () -> Unit) {
|
||||
current_track_play_pause.setOnClickListener {
|
||||
binding.currentTrackPlayPause.setOnClickListener {
|
||||
togglePlayback()
|
||||
}
|
||||
}
|
||||
|
||||
fun updateColors() {
|
||||
background = ColorDrawable(context.getProperBackgroundColor())
|
||||
current_track_label.setTextColor(context.getProperTextColor())
|
||||
binding.currentTrackLabel.setTextColor(context.getProperTextColor())
|
||||
}
|
||||
|
||||
fun updateCurrentTrack(mediaItem: MediaItem?) {
|
||||
|
@ -50,8 +47,8 @@ class CurrentTrackBar(context: Context, attributeSet: AttributeSet) : RelativeLa
|
|||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
current_track_label.text = "${track.title}$artist"
|
||||
val cornerRadius = resources.getDimension(R.dimen.rounded_corner_radius_small).toInt()
|
||||
binding.currentTrackLabel.text = "${track.title}$artist"
|
||||
val cornerRadius = resources.getDimension(com.simplemobiletools.commons.R.dimen.rounded_corner_radius_small).toInt()
|
||||
val currentTrackPlaceholder = resources.getColoredDrawableWithColor(R.drawable.ic_headset, context.getProperTextColor())
|
||||
val options = RequestOptions()
|
||||
.error(currentTrackPlaceholder)
|
||||
|
@ -68,6 +65,6 @@ class CurrentTrackBar(context: Context, attributeSet: AttributeSet) : RelativeLa
|
|||
}
|
||||
|
||||
fun updateTrackState(isPlaying: Boolean) {
|
||||
current_track_play_pause.updatePlayPauseIcon(isPlaying, context.getProperTextColor())
|
||||
binding.currentTrackPlayPause.updatePlayPauseIcon(isPlaying, context.getProperTextColor())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
package com.simplemobiletools.musicplayer.views
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.ViewGroup
|
||||
import com.google.android.material.tabs.TabLayout
|
||||
|
||||
// make the tabLayout scrollable horizotally when needed, else make sure it fills whole width
|
||||
class MyTabLayout : TabLayout {
|
||||
constructor(context: Context?) : super(context!!)
|
||||
constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs)
|
||||
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context!!, attrs, defStyleAttr)
|
||||
|
||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||
try {
|
||||
if (tabCount == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
val tabLayout = getChildAt(0) as ViewGroup
|
||||
val childCount = tabLayout.childCount
|
||||
val widths = IntArray(childCount + 1)
|
||||
|
||||
for (i in 0 until childCount) {
|
||||
widths[i] = tabLayout.getChildAt(i).measuredWidth
|
||||
widths[childCount] += widths[i]
|
||||
}
|
||||
|
||||
val measuredWidth = measuredWidth
|
||||
for (i in 0 until childCount) {
|
||||
tabLayout.getChildAt(i).minimumWidth = measuredWidth * widths[i] / widths[childCount]
|
||||
}
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -38,6 +38,7 @@
|
|||
</com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller>
|
||||
|
||||
<include
|
||||
android:id="@+id/current_track_bar"
|
||||
layout="@layout/view_current_track_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<include
|
||||
android:id="@+id/current_track_bar"
|
||||
layout="@layout/view_current_track_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
android:visibility="gone" />
|
||||
|
||||
<include
|
||||
android:id="@+id/current_track_bar"
|
||||
layout="@layout/view_current_track_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
@ -34,5 +34,3 @@
|
|||
|
||||
</com.qtalk.recyclerviewfastscroller.RecyclerViewFastScroller>
|
||||
</com.simplemobiletools.musicplayer.fragments.GenresFragment>
|
||||
|
||||
|
||||
|
|
30
build.gradle
30
build.gradle
|
@ -1,30 +0,0 @@
|
|||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.7.10'
|
||||
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
11
build.gradle.kts
Normal file
11
build.gradle.kts
Normal file
|
@ -0,0 +1,11 @@
|
|||
plugins {
|
||||
alias(libs.plugins.android).apply(false)
|
||||
alias(libs.plugins.kotlinAndroid).apply(false)
|
||||
alias(libs.plugins.ksp).apply(false)
|
||||
}
|
||||
|
||||
tasks.register<Delete>("clean") {
|
||||
delete {
|
||||
rootProject.buildDir
|
||||
}
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
android.enableJetifier=true
|
||||
android.useAndroidX=true
|
||||
android.useAndroidX=true
|
||||
org.gradle.jvmargs=-Xmx8192m
|
||||
|
|
69
gradle/libs.versions.toml
Normal file
69
gradle/libs.versions.toml
Normal file
|
@ -0,0 +1,69 @@
|
|||
[versions]
|
||||
#jetbrains
|
||||
autofittextview = "0.2.1"
|
||||
desugar_jdk_libs = "2.0.3"
|
||||
# higher versions of jaudiotagger not compatible with <= API 25 devices
|
||||
# https://bitbucket.org/ijabz/jaudiotagger/issues/149/some-nio-classes-are-unavailable-while
|
||||
jaudiotagger = "2.2.5"
|
||||
kotlin = "1.9.10"
|
||||
#KSP
|
||||
ksp = "1.9.10-1.0.13"
|
||||
#AndroidX
|
||||
androidx-constraintlayout = "2.1.4"
|
||||
androidx-swiperefreshlayout = "1.1.0"
|
||||
androidx-lifecycleprocess = "2.6.1"
|
||||
#Eventbus
|
||||
eventbus = "3.3.1"
|
||||
#Room
|
||||
lottie = "6.1.0"
|
||||
m3uParser = "1.3.0"
|
||||
media = "1.6.0"
|
||||
media3 = "1.1.1"
|
||||
room = "2.5.2"
|
||||
#Simple Mobile Tools
|
||||
simple-commons = "f64d11af6f"
|
||||
#Gradle
|
||||
gradlePlugins-agp = "8.1.0"
|
||||
#build
|
||||
app-build-compileSDKVersion = "34"
|
||||
app-build-targetSDK = "34"
|
||||
app-build-minimumSDK = "23"
|
||||
app-build-javaVersion = "VERSION_17"
|
||||
app-build-kotlinJVMTarget = "17"
|
||||
#Helpers
|
||||
shortcut-badger = "1.1.22"
|
||||
#versioning
|
||||
app-version-appId = "com.simplemobiletools.musicplayer"
|
||||
app-version-versionCode = "114"
|
||||
app-version-versionName = "5.17.1"
|
||||
[libraries]
|
||||
#AndroidX
|
||||
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "androidx-constraintlayout" }
|
||||
androidx-lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "androidx-lifecycleprocess" }
|
||||
androidx-media = { module = "androidx.media:media", version.ref = "media" }
|
||||
androidx-media3-exoplayer = { module = "androidx.media3:media3-exoplayer", version.ref = "media3" }
|
||||
androidx-media3-session = { module = "androidx.media3:media3-session", version.ref = "media3" }
|
||||
androidx-swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version.ref = "androidx-swiperefreshlayout" }
|
||||
#Room
|
||||
androidx-room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
|
||||
androidx-room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
|
||||
androidx-room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
|
||||
#Simple Mobile Tools
|
||||
simple-mobile-tools-commons = { module = "com.github.SimpleMobileTools:Simple-Commons", version.ref = "simple-commons" }
|
||||
#EventBus
|
||||
eventbus = { module = "org.greenrobot:eventbus", version.ref = "eventbus" }
|
||||
#Helpers
|
||||
desugar_jdk_libs = { module = "com.android.tools:desugar_jdk_libs", version.ref = "desugar_jdk_libs" }
|
||||
jaudiotagger = { module = "net.jthink:jaudiotagger", version.ref = "jaudiotagger" }
|
||||
lottie = { module = "com.airbnb.android:lottie", version.ref = "lottie" }
|
||||
autofittextview = { module = "me.grantland:autofittextview", version.ref = "autofittextview" }
|
||||
m3u-parser = { module = "com.github.bjoernpetersen:m3u-parser", version.ref = "m3uParser" }
|
||||
[bundles]
|
||||
room = [
|
||||
"androidx-room-ktx",
|
||||
"androidx-room-runtime",
|
||||
]
|
||||
[plugins]
|
||||
android = { id = "com.android.application", version.ref = "gradlePlugins-agp" }
|
||||
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
|||
#Mon Nov 02 17:54:10 CET 2020
|
||||
#Thu Aug 31 16:28:32 IST 2023
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
include ':app'
|
16
settings.gradle.kts
Normal file
16
settings.gradle.kts
Normal file
|
@ -0,0 +1,16 @@
|
|||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
maven { setUrl("https://jitpack.io") }
|
||||
}
|
||||
}
|
||||
include(":app")
|
Loading…
Reference in a new issue