diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index 8f2f9175..00000000 --- a/app/build.gradle +++ /dev/null @@ -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" -} diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 00000000..00dc29bf --- /dev/null +++ b/app/build.gradle.kts @@ -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 { + 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) +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 42c49666..48140e04 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -8,15 +8,17 @@ public ; } +# 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 ; } -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 diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 26931d45..390b7dbd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/AlbumsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/AlbumsActivity.kt index cd83109e..8ef74e6e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/AlbumsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/AlbumsActivity.kt @@ -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() {}.type val artist = Gson().fromJson(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) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/EqualizerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/EqualizerActivity.kt index 94647e65..fd416d14 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/EqualizerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/EqualizerActivity.kt @@ -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() private var bandSeekBars = ArrayList() + 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>() {}.type bands = Gson().fromJson>(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() (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]}" } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/ExcludedFoldersActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/ExcludedFoldersActivity.kt index c4bd8b24..82b6b42c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/ExcludedFoldersActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/ExcludedFoldersActivity.kt @@ -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 - 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() { diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/MainActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/MainActivity.kt index 604492ee..2a1d6ba5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/MainActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/MainActivity.kt @@ -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(R.id.tab_item_icon)?.setImageDrawable(getTabIcon(value)) - customView?.findViewById(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() - 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) diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/QueueActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/QueueActivity.kt index 0066e388..5162374c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/QueueActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/QueueActivity.kt @@ -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() + 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 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 - 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 - adapter.updateItems(currentTracks) - queue_list.lazySmoothScroll(shuffledMediaItemsIndices.indexOf(currentMediaItemIndex)) - } - } - private fun createPlaylistFromQueue() { NewPlaylistDialog(this) { newPlaylistId -> val tracks = ArrayList() diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SettingsActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SettingsActivity.kt index c5e21652..95575a33 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SettingsActivity.kt @@ -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) } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SimpleControllerActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SimpleControllerActivity.kt index 58f20900..751defed 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SimpleControllerActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SimpleControllerActivity.kt @@ -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, 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, 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 { diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SimpleMusicActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SimpleMusicActivity.kt index 74ba7e63..d100a66a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SimpleMusicActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/SimpleMusicActivity.kt @@ -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) diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/TrackActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/TrackActivity.kt index 265d84cf..222672da 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/TrackActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/TrackActivity.kt @@ -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()) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/TracksActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/TracksActivity.kt index 01b98d7d..24b14ec0 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/TracksActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/TracksActivity.kt @@ -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 - (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() - else -> (tracks_list.adapter as? TracksAdapter)?.items + TYPE_ALBUM -> (binding.tracksList.adapter as? TracksHeaderAdapter)?.items?.filterIsInstance() + 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 } ) } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/WidgetConfigureActivity.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/WidgetConfigureActivity.kt index f82c4f48..921b6ac1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/WidgetConfigureActivity.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/activities/WidgetConfigureActivity.kt @@ -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() { diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/AlbumsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/AlbumsAdapter.kt index 9499df85..d7d217b8 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/AlbumsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/AlbumsAdapter.kt @@ -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, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : BaseMusicAdapter(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, recyc } override fun getSelectedTracks(): List { - 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 - 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, 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) ?: "" } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/AlbumsTracksAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/AlbumsTracksAdapter.kt index c8d5b8d8..e68afbc3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/AlbumsTracksAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/AlbumsTracksAdapter.kt @@ -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() 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 { val tracks = getSelectedTracks().toMutableList() - tracks.addAll(ctx.audioHelper.getAlbumTracks(getSelectedAlbums())) + tracks.addAll(context.audioHelper.getAlbumTracks(getSelectedAlbums())) return tracks } private fun getSelectedAlbums(): List = getSelectedItems().filterIsInstance().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) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ArtistsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ArtistsAdapter.kt index 090c8c7d..114437eb 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ArtistsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ArtistsAdapter.kt @@ -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, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : BaseMusicAdapter(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, rec } override fun getSelectedTracks(): ArrayList { - 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 - 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, 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) ?: "" } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/BaseMusicAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/BaseMusicAdapter.kt index 4ad077dd..c3938a9e 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/BaseMusicAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/BaseMusicAdapter.kt @@ -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( 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( fun addToQueue() { ensureBackgroundThread { val allSelectedTracks = getAllSelectedTracks() - ctx.runOnUiThread { - ctx.addTracksToQueue(allSelectedTracks) { + context.runOnUiThread { + context.addTracksToQueue(allSelectedTracks) { finishActMode() } } @@ -102,8 +107,8 @@ abstract class BaseMusicAdapter( 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( 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( fun shareFiles() { ensureBackgroundThread { - ctx.shareFiles(getAllSelectedTracks()) + context.shareFiles(getAllSelectedTracks()) } } @@ -136,8 +141,8 @@ abstract class BaseMusicAdapter( return@ensureBackgroundThread } - ctx.runOnUiThread { - ctx.showTrackProperties(selectedTracks) + context.runOnUiThread { + context.showTrackProperties(selectedTracks) } } } @@ -147,13 +152,28 @@ abstract class BaseMusicAdapter( .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) + } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ExcludedFoldersAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ExcludedFoldersAdapter.kt index 042081a5..79274bb2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ExcludedFoldersAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ExcludedFoldersAdapter.kt @@ -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 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() } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/FoldersAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/FoldersAdapter.kt index 1d463bea..9637ae06 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/FoldersAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/FoldersAdapter.kt @@ -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 { val tracks = arrayListOf() 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) ?: "" } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/GenresAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/GenresAdapter.kt index a55edc7d..fc1587ce 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/GenresAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/GenresAdapter.kt @@ -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, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : BaseMusicAdapter(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, recyc } override fun getSelectedTracks(): ArrayList { - 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 - 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, 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) ?: "" } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/PlaylistsAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/PlaylistsAdapter.kt index f7c3cd86..09287ed4 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/PlaylistsAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/PlaylistsAdapter.kt @@ -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 if (delete) { ensureBackgroundThread { @@ -72,9 +73,9 @@ class PlaylistsAdapter( private fun deletePlaylistSongs(ids: ArrayList, 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 - 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) ?: "" } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/QueueAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/QueueAdapter.kt index 9963bffb..83cff7af 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/QueueAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/QueueAdapter.kt @@ -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, var currentTrack: Track? = null, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : BaseMusicAdapter(items, activity, recyclerView, itemClick), ItemTouchHelperContract, RecyclerViewFastScroller.OnPopupTextUpdate { @@ -46,7 +43,10 @@ class QueueAdapter(activity: SimpleActivity, items: ArrayList, 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, 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, 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() val selectedTracks = getSelectedTracks() selectedTracks.forEach { track -> @@ -117,14 +117,14 @@ class QueueAdapter(activity: SimpleActivity, items: ArrayList, var curren } } - ctx.deleteTracks(selectedTracks) { + context.deleteTracks(selectedTracks) { refreshTracksList(positions) } } } private fun refreshTracksList(positions: ArrayList) { - ctx.runOnUiThread { + context.runOnUiThread { positions.sortDescending() positions.forEach { items.removeAt(it) @@ -132,41 +132,45 @@ class QueueAdapter(activity: SimpleActivity, items: ArrayList, 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, 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, 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) diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/TracksAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/TracksAdapter.kt index e1ff3edd..5afe54d6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/TracksAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/TracksAdapter.kt @@ -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() 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) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/TracksHeaderAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/TracksHeaderAdapter.kt index ec2cd67c..f9ef9ae7 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/TracksHeaderAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/TracksHeaderAdapter.kt @@ -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, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit) : BaseMusicAdapter(items, activity, recyclerView, itemClick), RecyclerViewFastScroller.OnPopupTextUpdate { @@ -31,17 +28,17 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList, 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, override fun getIsItemSelectable(position: Int) = position != 0 private fun askConfirmDelete() { - ConfirmationDialog(ctx) { + ConfirmationDialog(context) { ensureBackgroundThread { val positions = ArrayList() val selectedTracks = getSelectedTracks() @@ -103,8 +100,8 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList, } } - 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, // 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, } 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, } @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(R.id.album_image).setImageDrawable(placeholderBig) + context.runOnUiThread { + albumImage.setImageDrawable(placeholderBig) } } } @@ -174,7 +171,7 @@ class TracksHeaderAdapter(activity: SimpleActivity, items: ArrayList, 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, 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, finishActMode() } - ctx.refreshQueueAndTracks(track) + context.refreshQueueAndTracks(track) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ViewPagerAdapter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ViewPagerAdapter.kt index 89d1d8f8..dee420fc 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ViewPagerAdapter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/adapters/ViewPagerAdapter.kt @@ -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() + 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() - 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 } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ChangeSortingDialog.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ChangeSortingDialog.kt index d120ff81..58720aa3 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ChangeSortingDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ChangeSortingDialog.kt @@ -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() 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(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) { diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/EditDialog.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/EditDialog.kt index de1e9cbf..c1ec2b98 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/EditDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/EditDialog.kt @@ -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) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ExportPlaylistDialog.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ExportPlaylistDialog.kt index 25e4d313..68485792 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ExportPlaylistDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ExportPlaylistDialog.kt @@ -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) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ManageVisibleTabsDialog.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ManageVisibleTabsDialog.kt index c07032d4..6a701b5c 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ManageVisibleTabsDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/ManageVisibleTabsDialog.kt @@ -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() + private val binding by activity.viewBinding(DialogManageVisibleTabsBinding::inflate) + private val tabs = LinkedHashMap() 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(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(value).isChecked) { + if (value.isChecked) { result += key } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/NewPlaylistDialog.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/NewPlaylistDialog.kt index 7f919754..14f22b76 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/NewPlaylistDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/NewPlaylistDialog.kt @@ -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) } } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/RemovePlaylistDialog.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/RemovePlaylistDialog.kt index f42f4699..6cab205f 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/RemovePlaylistDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/RemovePlaylistDialog.kt @@ -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) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/SelectPlaylistDialog.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/SelectPlaylistDialog.kt index 1aebb8ca..215298a1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/SelectPlaylistDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/SelectPlaylistDialog.kt @@ -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, view: View) { + private fun initDialog(playlists: ArrayList) { 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 } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/SleepTimerCustomDialog.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/SleepTimerCustomDialog.kt index 7707a16a..808ae21b 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/SleepTimerCustomDialog.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/dialogs/SleepTimerCustomDialog.kt @@ -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() diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/Context.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/Context.kt index 2d7e034e..1b44b468 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/Context.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/Context.kt @@ -242,16 +242,16 @@ fun Context.loadGlideResource( .load(model) .apply(options) .listener(object : RequestListener { - override fun onLoadFailed(e: GlideException?, model: Any?, target: Target?, isFirstResource: Boolean): Boolean { + override fun onLoadFailed(e: GlideException?, model: Any?, target: Target, isFirstResource: Boolean): Boolean { onLoadFailed(e) return true } override fun onResourceReady( resource: Drawable, - model: Any?, - target: Target?, - dataSource: DataSource?, + model: Any, + target: Target, + 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 diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/LottieAnimationView.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/LottieAnimationView.kt index d36c77a5..338e5e59 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/LottieAnimationView.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/LottieAnimationView.kt @@ -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) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/View.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/View.kt new file mode 100644 index 00000000..c912b548 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/extensions/View.kt @@ -0,0 +1,9 @@ +package com.simplemobiletools.musicplayer.extensions + +import android.view.View +import androidx.viewbinding.ViewBinding + +inline fun View.viewBinding(crossinline bind: (View) -> T) = + lazy(LazyThreadSafetyMode.NONE) { + bind(this) + } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/AlbumsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/AlbumsFragment.kt index d4da0469..f16ea8c9 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/AlbumsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/AlbumsFragment.kt @@ -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() + 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 - (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 } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/ArtistsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/ArtistsFragment.kt index 9f4ca581..07237014 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/ArtistsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/ArtistsFragment.kt @@ -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() + 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 - (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 } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/FoldersFragment.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/FoldersFragment.kt index 481b5ac4..81346f91 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/FoldersFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/FoldersFragment.kt @@ -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() + 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 - (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 } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/GenresFragment.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/GenresFragment.kt index 6856fd73..0ab10997 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/GenresFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/GenresFragment.kt @@ -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() + 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 - (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 } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/PlaybackSpeedFragment.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/PlaybackSpeedFragment.kt index 0e442f9a..a54fdab2 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/PlaybackSpeedFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/PlaybackSpeedFragment.kt @@ -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) diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/PlaylistsFragment.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/PlaylistsFragment.kt index a750b3b5..6a9a6fef 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/PlaylistsFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/PlaylistsFragment.kt @@ -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() + 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 - (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 } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/TracksFragment.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/TracksFragment.kt index 9e2c0be5..b0e48880 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/TracksFragment.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/fragments/TracksFragment.kt @@ -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() + 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 - (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 } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/M3uExporter.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/M3uExporter.kt index 961d03b4..a4c79124 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/M3uExporter.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/M3uExporter.kt @@ -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 -> diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/MyWidgetProvider.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/MyWidgetProvider.kt index b92639a5..bd14afa5 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/MyWidgetProvider.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/MyWidgetProvider.kt @@ -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)) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/NotificationHelper.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/NotificationHelper.kt index 675533ed..05978cbc 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/NotificationHelper.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/NotificationHelper.kt @@ -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) diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/SimpleMediaScanner.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/SimpleMediaScanner.kt index fdaa783a..2c10426a 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/SimpleMediaScanner.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/helpers/SimpleMediaScanner.kt @@ -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() diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/models/Folder.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/models/Folder.kt index daca8362..761cb2e6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/models/Folder.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/models/Folder.kt @@ -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() diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/CustomCommands.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/CustomCommands.kt index 4f96d2db..d87a95e1 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/CustomCommands.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/CustomCommands.kt @@ -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 { 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() ) } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/PlaybackService.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/PlaybackService.kt index b5320763..c78f2d93 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/PlaybackService.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/PlaybackService.kt @@ -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. } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/SimpleEqualizer.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/SimpleEqualizer.kt index 6fc6e180..69f57443 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/SimpleEqualizer.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/SimpleEqualizer.kt @@ -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) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/library/MediaItemProvider.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/library/MediaItemProvider.kt index cbb6b632..0329f447 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/library/MediaItemProvider.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/library/MediaItemProvider.kt @@ -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); diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/player/PlayerListener.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/player/PlayerListener.kt index 0a689e6f..b0a6bf5d 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/player/PlayerListener.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/player/PlayerListener.kt @@ -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) { diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/views/CurrentTrackBar.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/views/CurrentTrackBar.kt index 26fd1e4f..7ba2fab6 100644 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/views/CurrentTrackBar.kt +++ b/app/src/main/kotlin/com/simplemobiletools/musicplayer/views/CurrentTrackBar.kt @@ -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()) } } diff --git a/app/src/main/kotlin/com/simplemobiletools/musicplayer/views/MyTabLayout.kt b/app/src/main/kotlin/com/simplemobiletools/musicplayer/views/MyTabLayout.kt deleted file mode 100644 index 395144da..00000000 --- a/app/src/main/kotlin/com/simplemobiletools/musicplayer/views/MyTabLayout.kt +++ /dev/null @@ -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) { - } - } -} diff --git a/app/src/main/res/layout/activity_albums.xml b/app/src/main/res/layout/activity_albums.xml index be421b82..f3624dd3 100644 --- a/app/src/main/res/layout/activity_albums.xml +++ b/app/src/main/res/layout/activity_albums.xml @@ -38,6 +38,7 @@ - - diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 5dc760b4..00000000 --- a/build.gradle +++ /dev/null @@ -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 -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..28727709 --- /dev/null +++ b/build.gradle.kts @@ -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("clean") { + delete { + rootProject.buildDir + } +} diff --git a/gradle.properties b/gradle.properties index 5465fec0..95e3e292 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,3 @@ android.enableJetifier=true -android.useAndroidX=true \ No newline at end of file +android.useAndroidX=true +org.gradle.jvmargs=-Xmx8192m diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..47755618 --- /dev/null +++ b/gradle/libs.versions.toml @@ -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" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 30eef37e..1847f1cd 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -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 diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index e7b4def4..00000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include ':app' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000..45478cbe --- /dev/null +++ b/settings.gradle.kts @@ -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")