diff --git a/.gitignore b/.gitignore
index 37f05b7f5..6a32941f0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,8 +38,4 @@ obj/
captures
app/normal/release/
/models/
-
-app/font/
-app/src/debug/
-/app/nofont/
-/crowdin.properties
+/app/release/
diff --git a/README.md b/README.md
index 147dc995e..66b64c0dc 100644
--- a/README.md
+++ b/README.md
@@ -68,7 +68,7 @@ favorite songs. No other music player has this feature.
We are trying our best to bring you the best user experience. The app is regulary being updated for bug fixes and new features.
-### FAQ
+### ❓ FAQ
Please read the FAQ here: https://del.dog/RetroFaq
In any case, you find or notice any bugs please report them by
diff --git a/app/build.gradle b/app/build.gradle
index 3f4414d02..ebb6025a4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -34,7 +34,7 @@ android {
}
signingConfigs {
release {
- Properties properties = getProperties('/Users/h4h13/Documents/Github/retro.properties')
+ Properties properties = getProperties('/Users/apple/Documents/Github/retro.properties ')
storeFile file(getProperty(properties, 'storeFile'))
keyAlias getProperty(properties, 'keyAlias')
storePassword getProperty(properties, 'storePassword')
@@ -102,68 +102,50 @@ static def getDate() {
dependencies {
- implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(':appthemehelper')
implementation 'androidx.multidex:multidex:2.0.1'
-
implementation "androidx.gridlayout:gridlayout:1.0.0"
implementation "androidx.cardview:cardview:1.0.0"
- implementation "androidx.viewpager2:viewpager2:1.1.0-alpha01"
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.annotation:annotation:1.1.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
+ implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.preference:preference-ktx:1.1.1'
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.fragment:fragment-ktx:1.2.5'
implementation 'androidx.palette:palette-ktx:1.0.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta8'
- implementation 'androidx.recyclerview:recyclerview:1.1.0'
+ def nav_version = "2.3.0"
+ implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
+ implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
- implementation 'com.google.android.material:material:1.3.0-alpha01'
-
- def retrofit_version = '2.9.0'
- implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
- implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
-
- def material_dialog_version = "0.9.6.0"
- implementation "com.afollestad.material-dialogs:core:$material_dialog_version"
- implementation "com.afollestad.material-dialogs:commons:$material_dialog_version"
- implementation 'com.afollestad:material-cab:0.1.12'
-
- implementation 'com.github.bumptech.glide:glide:3.8.0'
- implementation 'com.github.bumptech.glide:okhttp3-integration:1.5.0'
- implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
-
- implementation('com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:0.11.0@aar') {
- transitive = true
- }
-
- def kotlin_coroutines_version = "1.3.8"
- implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
- implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
-
- implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:3.4.0.201406110918-r'
-
- implementation 'com.github.ksoichiro:android-observablescrollview:1.6.0'
- implementation 'com.github.kabouzeid:recyclerview-fastscroll:1.9-kmod'
-
- implementation 'com.github.AdrienPoupa:jaudiotagger:2.2.3'
-
- implementation 'com.anjlab.android.iab.v3:library:1.1.0'
- implementation 'com.r0adkll:slidableactivity:2.1.0'
- implementation 'com.heinrichreimersoftware:material-intro:1.6'
- implementation 'me.zhanghai.android.fastscroll:library:1.1.0'
+ def room_version = "2.2.5"
+ implementation "androidx.room:room-runtime:$room_version"
+ implementation "androidx.room:room-ktx:$room_version"
+ kapt "androidx.room:room-compiler:$room_version"
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
- implementation 'com.google.android.play:core:1.8.0'
- implementation 'me.jorgecastillo:androidcolorx:0.2.0'
- debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
- implementation 'com.github.dhaval2404:imagepicker:1.7.1'
+ implementation 'com.google.android.play:core-ktx:1.8.1'
+ implementation 'com.google.android.material:material:1.3.0-alpha01'
+
+ def retrofit_version = '2.9.0'
+ implementation "com.squareup.retrofit2:retrofit:$retrofit_version"
+ implementation "com.squareup.retrofit2:converter-gson:$retrofit_version"
+ implementation 'com.squareup.okhttp3:logging-interceptor:3.6.0'
+
+ def material_dialog_version = "0.9.6.0"
+ implementation "com.afollestad.material-dialogs:core:$material_dialog_version"
+ implementation "com.afollestad.material-dialogs:commons:$material_dialog_version"
+ implementation 'com.afollestad:material-cab:0.1.12'
+
+ def kotlin_coroutines_version = "1.3.8"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.4.10"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
def koin_version = "2.1.5"
implementation "org.koin:koin-core:$koin_version"
@@ -173,8 +155,22 @@ dependencies {
implementation "org.koin:koin-androidx-fragment:$koin_version"
implementation "org.koin:koin-androidx-ext:$koin_version"
- def nav_version = "2.3.0"
- implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
- implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
+ implementation 'com.github.bumptech.glide:glide:3.8.0'
+ implementation 'com.github.bumptech.glide:okhttp3-integration:1.5.0'
+ implementation 'com.h6ah4i.android.widget.advrecyclerview:advrecyclerview:1.0.0'
+
+ implementation 'org.eclipse.mylyn.github:org.eclipse.egit.github.core:3.4.0.201406110918-r'
+ implementation 'com.github.ksoichiro:android-observablescrollview:1.6.0'
+ implementation 'com.github.kabouzeid:recyclerview-fastscroll:1.9-kmod'
+ implementation 'com.github.AdrienPoupa:jaudiotagger:2.2.3'
+ implementation 'com.anjlab.android.iab.v3:library:1.1.0'
+ implementation 'com.r0adkll:slidableactivity:2.1.0'
+ implementation 'com.heinrichreimersoftware:material-intro:1.6'
+ implementation 'com.github.dhaval2404:imagepicker:1.7.1'
+ implementation 'org.jsoup:jsoup:1.11.1'
+ implementation 'me.zhanghai.android.fastscroll:library:1.1.0'
+ implementation 'me.jorgecastillo:androidcolorx:0.2.0'
+ implementation 'org.jsoup:jsoup:1.11.1'
+ debugImplementation 'com.amitshekhar.android:debug-db:1.0.6'
}
\ No newline at end of file
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
deleted file mode 100644
index b45c7e165..000000000
--- a/app/release/output-metadata.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "version": 1,
- "artifactType": {
- "type": "APK",
- "kind": "Directory"
- },
- "applicationId": "code.name.monkey.retromusic",
- "variantName": "release",
- "elements": [
- {
- "type": "SINGLE",
- "filters": [],
- "properties": [],
- "versionCode": 10438,
- "versionName": "3.5.650_0812",
- "enabled": true,
- "outputFile": "app-release.apk"
- }
- ]
-}
\ No newline at end of file
diff --git a/app/src/debug/res/font/bold.ttf b/app/src/debug/res/font/bold.ttf
new file mode 100644
index 000000000..96619df92
Binary files /dev/null and b/app/src/debug/res/font/bold.ttf differ
diff --git a/app/src/debug/res/font/google_sans_bold.ttf b/app/src/debug/res/font/google_sans_bold.ttf
new file mode 100644
index 000000000..80497666e
Binary files /dev/null and b/app/src/debug/res/font/google_sans_bold.ttf differ
diff --git a/app/src/debug/res/font/google_sans_medium.ttf b/app/src/debug/res/font/google_sans_medium.ttf
new file mode 100644
index 000000000..1543660da
Binary files /dev/null and b/app/src/debug/res/font/google_sans_medium.ttf differ
diff --git a/app/src/debug/res/font/google_sans_regular.ttf b/app/src/debug/res/font/google_sans_regular.ttf
new file mode 100644
index 000000000..ab605f9e2
Binary files /dev/null and b/app/src/debug/res/font/google_sans_regular.ttf differ
diff --git a/app/src/debug/res/font/medium.ttf b/app/src/debug/res/font/medium.ttf
new file mode 100644
index 000000000..fd818d6f5
Binary files /dev/null and b/app/src/debug/res/font/medium.ttf differ
diff --git a/app/src/debug/res/font/regular.ttf b/app/src/debug/res/font/regular.ttf
new file mode 100644
index 000000000..e2c69c3fb
Binary files /dev/null and b/app/src/debug/res/font/regular.ttf differ
diff --git a/app/src/debug/res/font/sans.xml b/app/src/debug/res/font/sans.xml
new file mode 100644
index 000000000..7bbc8513b
--- /dev/null
+++ b/app/src/debug/res/font/sans.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/debug/res/values/styles.xml b/app/src/debug/res/values/styles.xml
new file mode 100644
index 000000000..81154a395
--- /dev/null
+++ b/app/src/debug/res/values/styles.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index bb4f033df..11590b31d 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -255,11 +255,9 @@
+
-
diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png
index f9c45db6b..a4a872d34 100644
Binary files a/app/src/main/ic_launcher-playstore.png and b/app/src/main/ic_launcher-playstore.png differ
diff --git a/app/src/main/java/code/name/monkey/retromusic/Constants.kt b/app/src/main/java/code/name/monkey/retromusic/Constants.kt
index 0f037ba76..4e3a7a241 100644
--- a/app/src/main/java/code/name/monkey/retromusic/Constants.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/Constants.kt
@@ -31,7 +31,7 @@ object Constants {
const val APP_TWITTER_LINK = "https://twitter.com/retromusicapp"
const val FAQ_LINK = "https://github.com/h4h13/RetroMusicPlayer/blob/master/FAQ.md"
const val PINTEREST = "https://in.pinterest.com/retromusicapp/"
- const val BASE_URL = "https://ws.audioscrobbler.com/2.0/"
+ const val AUDIO_SCROBBLER_URL = "https://ws.audioscrobbler.com/2.0/"
const val IS_MUSIC =
MediaStore.Audio.AudioColumns.IS_MUSIC + "=1" + " AND " + MediaStore.Audio.AudioColumns.TITLE + " != ''"
@@ -55,9 +55,11 @@ object Constants {
}
const val EXTRA_GENRE = "extra_genre"
const val EXTRA_PLAYLIST = "extra_playlist"
+const val EXTRA_PLAYLIST_ID = "extra_playlist_id"
const val EXTRA_ALBUM_ID = "extra_album_id"
const val EXTRA_ARTIST_ID = "extra_artist_id"
const val EXTRA_SONG = "extra_songs"
+const val EXTRA_PLAYLISTS = "extra_playlists"
const val LIBRARY_CATEGORIES = "library_categories"
const val EXTRA_SONG_INFO = "extra_song_info"
const val DESATURATED_COLOR = "desaturated_color"
@@ -68,8 +70,8 @@ const val NOW_PLAYING_SCREEN_ID = "now_playing_screen_id"
const val CAROUSEL_EFFECT = "carousel_effect"
const val COLORED_NOTIFICATION = "colored_notification"
const val CLASSIC_NOTIFICATION = "classic_notification"
-const val GAPLESS_PLAYBACK = "gapless_playback"
-const val ALBUM_ART_ON_LOCKSCREEN = "album_art_on_lockscreen"
+const val GAP_LESS_PLAYBACK = "gap_less_playback"
+const val ALBUM_ART_ON_LOCK_SCREEN = "album_art_on_lock_screen"
const val BLURRED_ALBUM_ART = "blurred_album_art"
const val NEW_BLUR_AMOUNT = "new_blur_amount"
const val TOGGLE_HEADSET = "toggle_headset"
@@ -90,7 +92,6 @@ const val ALBUM_COVER_STYLE = "album_cover_style_id"
const val ALBUM_COVER_TRANSFORM = "album_cover_transform"
const val TAB_TEXT_MODE = "tab_text_mode"
const val LANGUAGE_NAME = "language_name"
-const val DIALOG_CORNER = "dialog_corner"
const val SLEEP_TIMER_FINISH_SONG = "sleep_timer_finish_song"
const val ALBUM_GRID_STYLE = "album_grid_style_home"
const val ARTIST_GRID_STYLE = "artist_grid_style_home"
diff --git a/app/src/main/java/code/name/monkey/retromusic/HomeSection.kt b/app/src/main/java/code/name/monkey/retromusic/HomeSection.kt
index 80574b8a5..f53120543 100644
--- a/app/src/main/java/code/name/monkey/retromusic/HomeSection.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/HomeSection.kt
@@ -22,4 +22,7 @@ const val TOP_ARTISTS = 0
const val SUGGESTIONS = 5
const val FAVOURITES = 4
const val GENRES = 6
-const val PLAYLISTS = 7
\ No newline at end of file
+const val PLAYLISTS = 7
+const val HISTORY_PLAYLIST = 8
+const val LAST_ADDED_PLAYLIST = 9
+const val TOP_PLAYED_PLAYLIST = 10
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/MainModule.kt b/app/src/main/java/code/name/monkey/retromusic/MainModule.kt
index f1e52df6d..c7296dda8 100644
--- a/app/src/main/java/code/name/monkey/retromusic/MainModule.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/MainModule.kt
@@ -1,5 +1,12 @@
package code.name.monkey.retromusic
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import androidx.sqlite.db.SupportSQLiteDatabase
+import code.name.monkey.retromusic.db.BlackListStoreDao
+import code.name.monkey.retromusic.db.BlackListStoreEntity
+import code.name.monkey.retromusic.db.PlaylistWithSongs
+import code.name.monkey.retromusic.db.RetroDatabase
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.albums.AlbumDetailsViewModel
import code.name.monkey.retromusic.fragments.artists.ArtistDetailsViewModel
@@ -7,17 +14,103 @@ import code.name.monkey.retromusic.fragments.genres.GenreDetailsViewModel
import code.name.monkey.retromusic.fragments.playlists.PlaylistDetailsViewModel
import code.name.monkey.retromusic.fragments.search.SearchViewModel
import code.name.monkey.retromusic.model.Genre
-import code.name.monkey.retromusic.model.Playlist
-import code.name.monkey.retromusic.network.networkModule
+import code.name.monkey.retromusic.network.*
import code.name.monkey.retromusic.repository.*
+import code.name.monkey.retromusic.util.FilePathUtil
+import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.GlobalScope
+import kotlinx.coroutines.launch
import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.bind
import org.koin.dsl.module
+val networkModule = module {
+
+ factory {
+ provideDefaultCache()
+ }
+ factory {
+ provideOkHttp(get(), get())
+ }
+ single {
+ provideLastFmRetrofit(get())
+ }
+ single {
+ provideDeezerRest(get())
+ }
+ single {
+ provideLastFmRest(get())
+ }
+ single {
+ provideLyrics(get())
+ }
+}
+
+private val roomModule = module {
+
+ single {
+ Room.databaseBuilder(androidContext(), RetroDatabase::class.java, "playlist.db")
+ .allowMainThreadQueries()
+ .addCallback(object : RoomDatabase.Callback() {
+ override fun onOpen(db: SupportSQLiteDatabase) {
+ super.onOpen(db)
+ GlobalScope.launch(IO) {
+ FilePathUtil.blacklistFilePaths().map {
+ get().insertBlacklistPath(BlackListStoreEntity(it))
+ }
+ }
+ }
+ })
+ .fallbackToDestructiveMigration()
+ .build()
+ }
+ factory {
+ get().lyricsDao()
+ }
+
+ factory {
+ get().playlistDao()
+ }
+
+ factory {
+ get().blackListStore()
+ }
+
+ factory {
+ get().playCountDao()
+ }
+
+ factory {
+ get().historyDao()
+ }
+
+ single {
+ RealRoomRepository(get(), get(), get(), get(), get())
+ } bind RoomRepository::class
+}
+private val mainModule = module {
+ single {
+ androidContext().contentResolver
+ }
+
+}
private val dataModule = module {
single {
- RealRepository(get(), get(), get(), get(), get(), get(), get(), get(), get(), get())
+ RealRepository(
+ get(),
+ get(),
+ get(),
+ get(),
+ get(),
+ get(),
+ get(),
+ get(),
+ get(),
+ get(),
+ get(),
+ get()
+ )
} bind Repository::class
single {
@@ -61,10 +154,6 @@ private val dataModule = module {
get()
)
}
-
- single {
- androidContext().contentResolver
- }
}
private val viewModules = module {
@@ -87,7 +176,7 @@ private val viewModules = module {
)
}
- viewModel { (playlist: Playlist) ->
+ viewModel { (playlist: PlaylistWithSongs) ->
PlaylistDetailsViewModel(
get(),
playlist
@@ -106,4 +195,4 @@ private val viewModules = module {
}
}
-val appModules = listOf(dataModule, viewModules, networkModule)
\ No newline at end of file
+val appModules = listOf(mainModule, dataModule, viewModules, networkModule, roomModule)
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt
index 4d6cef1fd..13b75956d 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/DriveModeActivity.kt
@@ -218,7 +218,7 @@ class DriveModeActivity : AbsMusicServiceActivity(), Callback {
.build()
.transform(BlurTransformation.Builder(this).build())
.into(object : RetroMusicColoredTarget(image) {
- override fun onColorReady(color: MediaNotificationProcessor) {
+ override fun onColorReady(colors: MediaNotificationProcessor) {
}
})
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt
index 16491accd..ff8559470 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/MainActivity.kt
@@ -3,30 +3,23 @@ package code.name.monkey.retromusic.activities
import android.content.Intent
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
+import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
-import android.util.Log
import android.view.View
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.extensions.findNavController
-import code.name.monkey.retromusic.fragments.LibraryViewModel
-import code.name.monkey.retromusic.helper.MusicPlayerRemote.openAndShuffleQueue
-import code.name.monkey.retromusic.helper.MusicPlayerRemote.openQueue
-import code.name.monkey.retromusic.helper.MusicPlayerRemote.playFromUri
-import code.name.monkey.retromusic.helper.MusicPlayerRemote.shuffleMode
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SearchQueryHelper.getSongs
import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.repository.PlaylistSongsLoader.getPlaylistSongList
-import code.name.monkey.retromusic.repository.Repository
+import code.name.monkey.retromusic.repository.PlaylistSongsLoader
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.AppRater.appLaunched
import code.name.monkey.retromusic.util.PreferenceUtil
-import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
-import org.koin.android.ext.android.inject
-import java.util.*
class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeListener {
companion object {
@@ -35,9 +28,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
const val APP_UPDATE_REQUEST_CODE = 9002
}
- private val repository by inject()
- private val libraryViewModel by inject()
-
private var blockRequestPermissions = false
override fun createContentView(): View {
@@ -53,7 +43,6 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
setTaskDescriptionColorAuto()
hideStatusBar()
appLaunched(this)
- addMusicServiceEventListener(libraryViewModel)
updateTabs()
}
@@ -99,61 +88,68 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
override fun onServiceConnected() {
super.onServiceConnected()
- handlePlaybackIntent(intent)
- }
-
- private fun handlePlaybackIntent(intent: Intent?) {
if (intent == null) {
return
}
- val uri = intent.data
- val mimeType = intent.type
- var handled = false
- if (intent.action != null && (intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH)
- ) {
- val songs: List =
- getSongs(this, intent.extras!!)
- if (shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
- openAndShuffleQueue(songs, true)
- } else {
- openQueue(songs, 0, true)
- }
- handled = true
- }
- if (uri != null && uri.toString().isNotEmpty()) {
- playFromUri(uri)
- handled = true
- } else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) {
- val id = parseIdFromIntent(intent, "playlistId", "playlist").toInt()
- if (id >= 0) {
- val position = intent.getIntExtra("position", 0)
- val songs: List =
- ArrayList(getPlaylistSongList(this, id))
- openQueue(songs, position, true)
+ handlePlaybackIntent(intent)
+ }
+
+ private fun handlePlaybackIntent(intent: Intent) {
+ lifecycleScope.launch(IO) {
+ val uri: Uri? = intent.data
+ val mimeType: String? = intent.type
+ var handled = false
+ if (intent.action != null &&
+ intent.action == MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
+ ) {
+ val songs: List = getSongs(intent.extras!!)
+ if (MusicPlayerRemote.shuffleMode == MusicService.SHUFFLE_MODE_SHUFFLE) {
+ MusicPlayerRemote.openAndShuffleQueue(songs, true)
+ } else {
+ MusicPlayerRemote.openQueue(songs, 0, true)
+ }
handled = true
}
- } else if (MediaStore.Audio.Albums.CONTENT_TYPE == mimeType) {
- val id = parseIdFromIntent(intent, "albumId", "album").toInt()
- if (id >= 0) {
- lifecycleScope.launch(Dispatchers.Main) {
- val position = intent.getIntExtra("position", 0)
- openQueue(repository.albumById(id).songs!!, position, true)
+ if (uri != null && uri.toString().isNotEmpty()) {
+ MusicPlayerRemote.playFromUri(uri)
+ handled = true
+ } else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) {
+ val id: Int = parseIdFromIntent(intent, "playlistId", "playlist").toInt()
+ if (id >= 0) {
+ val position: Int = intent.getIntExtra("position", 0)
+ val songs: List =
+ PlaylistSongsLoader.getPlaylistSongList(this@MainActivity, id)
+ MusicPlayerRemote.openQueue(songs, position, true)
+ handled = true
+ }
+ } else if (MediaStore.Audio.Albums.CONTENT_TYPE == mimeType) {
+ val id = parseIdFromIntent(intent, "albumId", "album").toInt()
+ if (id >= 0) {
+ val position: Int = intent.getIntExtra("position", 0)
+ MusicPlayerRemote.openQueue(
+ libraryViewModel.albumById(id).songs!!,
+ position,
+ true
+ )
+ handled = true
+ }
+ } else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
+ val id: Int = parseIdFromIntent(intent, "artistId", "artist").toInt()
+ if (id >= 0) {
+ val position: Int = intent.getIntExtra("position", 0)
+ MusicPlayerRemote.openQueue(
+ libraryViewModel.artistById(id).songs,
+ position,
+ true
+ )
handled = true
}
}
- } else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) {
- val id = parseIdFromIntent(intent, "artistId", "artist").toInt()
- if (id >= 0) {
- lifecycleScope.launch {
- val position = intent.getIntExtra("position", 0)
- openQueue(repository.artistById(id).songs, position, true)
- handled = true
- }
+ if (handled) {
+ setIntent(Intent())
}
}
- if (handled) {
- setIntent(Intent())
- }
+
}
private fun parseIdFromIntent(
@@ -167,7 +163,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis
try {
id = idString.toLong()
} catch (e: NumberFormatException) {
- Log.e(TAG, e.message)
+ println(e.message)
}
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/PlayingQueueActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/PlayingQueueActivity.kt
index e15d4e154..9906db0b9 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/PlayingQueueActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/PlayingQueueActivity.kt
@@ -104,7 +104,7 @@ open class PlayingQueueActivity : AbsMusicServiceActivity() {
}
}
})
- val fastScroller = ThemedFastScroller.create(recyclerView)
+ ThemedFastScroller.create(recyclerView)
}
private fun checkForPadding() {
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt
index 410d68143..99d30ab70 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/PurchaseActivity.kt
@@ -108,7 +108,7 @@ class PurchaseActivity : AbsBaseActivity(), BillingProcessor.IBillingHandler {
super.onDestroy()
}
- private class RestorePurchaseAsyncTask internal constructor(purchaseActivity: PurchaseActivity) :
+ private class RestorePurchaseAsyncTask(purchaseActivity: PurchaseActivity) :
AsyncTask() {
private val buyActivityWeakReference: WeakReference = WeakReference(
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt
index 66bd0aa8e..b20d70458 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/SupportDevelopmentActivity.kt
@@ -110,7 +110,7 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH
}
if (requestCode == TEZ_REQUEST_CODE) {
// Process based on the data in response.
- Log.d("result", data!!.getStringExtra("Status"))
+ //Log.d("result", data!!.getStringExtra("Status"))
}
}
@@ -121,7 +121,7 @@ class SupportDevelopmentActivity : AbsBaseActivity(), BillingProcessor.IBillingH
}
}
-private class SkuDetailsLoadAsyncTask internal constructor(supportDevelopmentActivity: SupportDevelopmentActivity) :
+private class SkuDetailsLoadAsyncTask(supportDevelopmentActivity: SupportDevelopmentActivity) :
AsyncTask>() {
private val weakReference: WeakReference = WeakReference(
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/UserInfoActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/UserInfoActivity.kt
index 904f48ff3..a97642f4e 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/UserInfoActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/UserInfoActivity.kt
@@ -160,7 +160,7 @@ class UserInfoActivity : AbsBaseActivity() {
}
private fun saveImage(bitmap: Bitmap, fileName: String) {
- CoroutineScope(Dispatchers.IO).launch() {
+ CoroutineScope(Dispatchers.IO).launch {
val appDir = applicationContext.filesDir
val file = File(appDir, fileName)
var successful = false
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsMusicServiceActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsMusicServiceActivity.kt
index 9057625fd..1e9efee87 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsMusicServiceActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsMusicServiceActivity.kt
@@ -4,17 +4,23 @@ import android.Manifest
import android.content.*
import android.os.Bundle
import android.os.IBinder
+import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.db.toPlayCount
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener
+import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.service.MusicService.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import org.koin.android.ext.android.inject
import java.lang.ref.WeakReference
import java.util.*
abstract class AbsMusicServiceActivity : AbsBaseActivity(), MusicServiceEventListener {
private val mMusicServiceEventListeners = ArrayList()
-
+ private val repository: RealRepository by inject()
private var serviceToken: MusicPlayerRemote.ServiceToken? = null
private var musicStateReceiver: MusicStateReceiver? = null
private var receiverRegistered: Boolean = false
@@ -93,6 +99,22 @@ abstract class AbsMusicServiceActivity : AbsBaseActivity(), MusicServiceEventLis
for (listener in mMusicServiceEventListeners) {
listener.onPlayingMetaChanged()
}
+ lifecycleScope.launch(Dispatchers.IO) {
+ val entity = repository.songPresentInHistory(MusicPlayerRemote.currentSong)
+ if (entity != null) {
+ repository.updateHistorySong(MusicPlayerRemote.currentSong)
+ } else {
+ repository.addSongToHistory(MusicPlayerRemote.currentSong)
+ }
+ val songs = repository.checkSongExistInPlayCount(MusicPlayerRemote.currentSong.id)
+ if (songs.isNotEmpty()) {
+ repository.updateSongInPlayCount(songs.first().apply {
+ playCount += 1
+ })
+ } else {
+ repository.insertSongInPlayCount(MusicPlayerRemote.currentSong.toPlayCount())
+ }
+ }
}
override fun onQueueChanged() {
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt
index d0dbdb340..540982793 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/base/AbsSlidingMusicPanelActivity.kt
@@ -15,7 +15,6 @@ import code.name.monkey.appthemehelper.util.ColorUtil
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.RetroBottomSheetBehavior
import code.name.monkey.retromusic.extensions.hide
-import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.MiniPlayerFragment
@@ -29,12 +28,12 @@ import com.google.android.material.bottomsheet.BottomSheetBehavior
import kotlinx.android.synthetic.main.sliding_music_panel_layout.*
import org.koin.androidx.viewmodel.ext.android.viewModel
-abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
+abstract class AbsSlidingMusicPanelActivity : AbsMusicServiceActivity() {
companion object {
val TAG: String = AbsSlidingMusicPanelActivity::class.java.simpleName
}
- private val libraryViewModel by viewModel()
+ protected val libraryViewModel by viewModel()
private lateinit var behavior: RetroBottomSheetBehavior
private var miniPlayerFragment: MiniPlayerFragment? = null
private var cps: NowPlayingScreen? = null
@@ -51,8 +50,6 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
setMiniPlayerAlphaProgress(slideOffset)
- dimBackground.show()
- dimBackground.alpha = slideOffset
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
@@ -62,7 +59,6 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
}
BottomSheetBehavior.STATE_COLLAPSED -> {
onPanelCollapsed()
- dimBackground.hide()
}
else -> {
@@ -77,13 +73,9 @@ abstract class AbsSlidingMusicPanelActivity() : AbsMusicServiceActivity() {
setContentView(createContentView())
chooseFragmentForTheme()
setupSlidingUpPanel()
- addMusicServiceEventListener(libraryViewModel)
setupBottomSheet()
- val themeColor = ATHUtil.resolveColor(this, android.R.attr.windowBackground, Color.GRAY)
- dimBackground.setBackgroundColor(ColorUtil.withAlpha(themeColor, 0.5f))
-
libraryViewModel.paletteColorLiveData.observe(this, Observer {
this.paletteColor = it
onPaletteColorChanged()
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt
index 418ded1dd..5bb2b7aca 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/BugReportActivity.kt
@@ -295,7 +295,7 @@ open class BugReportActivity : AbsThemeActivity() {
.setTitle(R.string.bug_report_failed)
.setMessage(R.string.bug_report_failed_unknown)
.setPositiveButton(android.R.string.ok) { _, _ -> tryToFinishActivity() }
- .setNegativeButton(android.R.string.cancel) { _, _ -> { tryToFinishActivity() } }
+ .setNegativeButton(android.R.string.cancel) { _, _ -> tryToFinishActivity() }
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/model/DeviceInfo.java b/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/model/DeviceInfo.java
index e9eee8a23..3a6e80328 100644
--- a/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/model/DeviceInfo.java
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/bugreport/model/DeviceInfo.java
@@ -85,7 +85,7 @@ public class DeviceInfo {
return "Device info:\n"
+ "---\n"
+ "\n"
- + "App version | " + versionName + " |
\n"
+ + "App version | " + versionName + " |
\n"
+ "App version code | " + versionCode + " |
\n"
+ "Android build version | " + buildVersion + " |
\n"
+ "Android release version | " + releaseVersion + " |
\n"
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt
index d9f006e71..1571e07ae 100755
--- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AbsTagEditorActivity.kt
@@ -14,7 +14,6 @@ import android.view.MenuItem
import android.view.View
import android.view.animation.OvershootInterpolator
import androidx.appcompat.app.AlertDialog
-import androidx.lifecycle.lifecycleScope
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.ColorUtil
@@ -182,11 +181,9 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
saveFab = findViewById(R.id.saveTags)
getIntentExtras()
- lifecycleScope.launchWhenCreated {
- songPaths = getSongPaths()
- if (songPaths!!.isEmpty()) {
- finish()
- }
+ songPaths = getSongPaths()
+ if (songPaths!!.isEmpty()) {
+ finish()
}
setUpViews()
}
@@ -258,7 +255,7 @@ abstract class AbsTagEditorActivity : AbsBaseActivity() {
}
}
- protected abstract suspend fun getSongPaths(): List
+ protected abstract fun getSongPaths(): List
protected fun searchWebFor(vararg keys: String) {
val stringBuilder = StringBuilder()
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt
index ca67e93b4..8a908dd66 100755
--- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/AlbumTagEditorActivity.kt
@@ -44,9 +44,9 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
window.enterTransition = slide
}
- override fun loadImageFromFile(selectedFileUri: Uri?) {
+ override fun loadImageFromFile(selectedFile: Uri?) {
- Glide.with(this@AlbumTagEditorActivity).load(selectedFileUri).asBitmap()
+ Glide.with(this@AlbumTagEditorActivity).load(selectedFile).asBitmap()
.transcode(BitmapPaletteTranscoder(this), BitmapPaletteWrapper::class.java)
.diskCacheStrategy(DiskCacheStrategy.NONE).skipMemoryCache(true)
.into(object : SimpleTarget() {
@@ -167,7 +167,7 @@ class AlbumTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
)
}
- override suspend fun getSongPaths(): List {
+ override fun getSongPaths(): List {
val songs = repository.albumById(id).songs
val paths = ArrayList(songs!!.size)
for (song in songs) {
diff --git a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt
index 5e3d5909a..35b02bda3 100755
--- a/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/activities/tageditor/SongTagEditorActivity.kt
@@ -88,7 +88,7 @@ class SongTagEditorActivity : AbsTagEditorActivity(), TextWatcher {
writeValuesToFiles(fieldKeyValueMap, null)
}
- override suspend fun getSongPaths(): List {
+ override fun getSongPaths(): List {
val paths = ArrayList(1)
paths.add(songRepository.song(id).data)
return paths
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt
index a015b1ad6..bf9f1c913 100644
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/GenreAdapter.kt
@@ -1,5 +1,6 @@
package code.name.monkey.retromusic.adapter
+import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -22,14 +23,14 @@ class GenreAdapter(
var dataSet: List,
private val mItemLayoutRes: Int
) : RecyclerView.Adapter() {
-
-
+ val colors = listOf(Color.RED, Color.BLUE)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(LayoutInflater.from(activity).inflate(mItemLayoutRes, parent, false))
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val genre = dataSet[position]
+
holder.title?.text = genre.name
holder.text?.text = String.format(
Locale.getDefault(),
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt
index b08b15df0..0ed2272b1 100644
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/HomeAdapter.kt
@@ -40,8 +40,8 @@ class HomeAdapter(
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- val layout = LayoutInflater.from(activity)
- .inflate(R.layout.section_recycler_view, parent, false)
+ val layout =
+ LayoutInflater.from(activity).inflate(R.layout.section_recycler_view, parent, false)
return when (viewType) {
RECENT_ARTISTS, TOP_ARTISTS -> ArtistViewHolder(layout)
GENRES -> GenreViewHolder(layout)
@@ -64,7 +64,7 @@ class HomeAdapter(
when (getItemViewType(position)) {
RECENT_ALBUMS -> {
val viewHolder = holder as AlbumViewHolder
- viewHolder.bindView(home.arrayList as List, R.string.recent_albums)
+ viewHolder.bindView(home)
viewHolder.clickableArea.setOnClickListener {
activity.findNavController(R.id.fragment_container).navigate(
R.id.detailListFragment,
@@ -74,7 +74,7 @@ class HomeAdapter(
}
TOP_ALBUMS -> {
val viewHolder = holder as AlbumViewHolder
- viewHolder.bindView(home.arrayList as List, R.string.top_albums)
+ viewHolder.bindView(home)
viewHolder.clickableArea.setOnClickListener {
activity.findNavController(R.id.fragment_container).navigate(
R.id.detailListFragment,
@@ -84,7 +84,7 @@ class HomeAdapter(
}
RECENT_ARTISTS -> {
val viewHolder = holder as ArtistViewHolder
- viewHolder.bindView(home.arrayList, R.string.recent_artists)
+ viewHolder.bindView(home)
viewHolder.clickableArea.setOnClickListener {
activity.findNavController(R.id.fragment_container).navigate(
R.id.detailListFragment,
@@ -94,7 +94,7 @@ class HomeAdapter(
}
TOP_ARTISTS -> {
val viewHolder = holder as ArtistViewHolder
- viewHolder.bindView(home.arrayList, R.string.top_artists)
+ viewHolder.bindView(home)
viewHolder.clickableArea.setOnClickListener {
activity.findNavController(R.id.fragment_container).navigate(
R.id.detailListFragment,
@@ -104,15 +104,21 @@ class HomeAdapter(
}
SUGGESTIONS -> {
val viewHolder = holder as SuggestionsViewHolder
- viewHolder.bindView(home.arrayList)
+ viewHolder.bindView(home)
}
FAVOURITES -> {
val viewHolder = holder as PlaylistViewHolder
- viewHolder.bindView(home.arrayList, R.string.favorites)
+ viewHolder.bindView(home)
+ viewHolder.clickableArea.setOnClickListener {
+ activity.findNavController(R.id.fragment_container).navigate(
+ R.id.detailListFragment,
+ bundleOf("type" to FAVOURITES)
+ )
+ }
}
GENRES -> {
val viewHolder = holder as GenreViewHolder
- viewHolder.bind(home.arrayList, R.string.genres)
+ viewHolder.bind(home)
}
PLAYLISTS -> {
@@ -130,22 +136,22 @@ class HomeAdapter(
}
private inner class AlbumViewHolder(view: View) : AbsHomeViewItem(view) {
- fun bindView(albums: List, titleRes: Int) {
- title.text = activity.getString(titleRes)
+ fun bindView(home: Home) {
+ title.setText(home.titleRes)
recyclerView.apply {
- adapter = albumAdapter(albums)
+ adapter = albumAdapter(home.arrayList as List)
layoutManager = gridLayoutManager()
}
}
}
private inner class ArtistViewHolder(view: View) : AbsHomeViewItem(view) {
- fun bindView(artists: List, titleRes: Int) {
+ fun bindView(home: Home) {
+ title.setText(home.titleRes)
recyclerView.apply {
layoutManager = linearLayoutManager()
- adapter = artistsAdapter(artists as List)
+ adapter = artistsAdapter(home.arrayList as List)
}
- title.text = activity.getString(titleRes)
}
}
@@ -161,8 +167,7 @@ class HomeAdapter(
R.id.image8
)
- fun bindView(songs: List) {
- songs as List
+ fun bindView(home: Home) {
val color = ThemeStore.accentColor(activity)
itemView.findViewById(R.id.message).setTextColor(color)
itemView.findViewById(R.id.card6).apply {
@@ -170,9 +175,9 @@ class HomeAdapter(
}
images.forEachIndexed { index, id ->
itemView.findViewById(id).setOnClickListener {
- MusicPlayerRemote.playNext(songs[index])
+ MusicPlayerRemote.playNext(home.arrayList[index] as Song)
}
- SongGlideRequest.Builder.from(Glide.with(activity), songs[index])
+ SongGlideRequest.Builder.from(Glide.with(activity), home.arrayList[index] as Song)
.asBitmap()
.build()
.into(itemView.findViewById(id))
@@ -182,35 +187,37 @@ class HomeAdapter(
}
private inner class PlaylistViewHolder(view: View) : AbsHomeViewItem(view) {
- fun bindView(songs: List, titleRes: Int) {
- arrow.hide()
+ fun bindView(home: Home) {
+ title.setText(home.titleRes)
recyclerView.apply {
val songAdapter = SongAdapter(
activity,
- songs as MutableList,
+ home.arrayList as MutableList,
R.layout.item_album_card, null
)
layoutManager = linearLayoutManager()
adapter = songAdapter
}
- title.text = activity.getString(titleRes)
}
}
private inner class GenreViewHolder(itemView: View) : AbsHomeViewItem(itemView) {
- fun bind(genres: List, titleRes: Int) {
+ fun bind(home: Home) {
arrow.hide()
- title.text = activity.getString(titleRes)
+ title.setText(home.titleRes)
+ val genreAdapter = GenreAdapter(
+ activity,
+ home.arrayList as List,
+ R.layout.item_grid_genre
+ )
recyclerView.apply {
layoutManager = GridLayoutManager(activity, 3, GridLayoutManager.HORIZONTAL, false)
- val genreAdapter =
- GenreAdapter(activity, genres as List, R.layout.item_grid_genre)
adapter = genreAdapter
}
}
}
- open inner class AbsHomeViewItem(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ open class AbsHomeViewItem(itemView: View) : RecyclerView.ViewHolder(itemView) {
val recyclerView: RecyclerView = itemView.findViewById(R.id.recyclerView)
val title: AppCompatTextView = itemView.findViewById(R.id.title)
val arrow: ImageView = itemView.findViewById(R.id.arrow)
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt
index c372b45cb..97e2ada1d 100644
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/SearchAdapter.kt
@@ -60,7 +60,7 @@ class SearchAdapter(
holder.title?.text = album.title
holder.text?.text = album.artistName
AlbumGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
- .checkIgnoreMediaStore(activity).build().into(holder.image)
+ .checkIgnoreMediaStore().build().into(holder.image)
}
ARTIST -> {
val artist = dataSet.get(position) as Artist
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt
index 73c8b09e3..8cb9f9d88 100644
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumAdapter.kt
@@ -101,11 +101,10 @@ open class AlbumAdapter(
}
AlbumGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
- .checkIgnoreMediaStore(activity)
+ .checkIgnoreMediaStore()
.generatePalette(activity)
.build()
.into(object : RetroMusicColoredTarget(holder.image!!) {
-
override fun onColorReady(colors: MediaNotificationProcessor) {
setColors(colors, holder)
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt
index 039aa9fe2..1a82f465f 100644
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/album/AlbumCoverPagerAdapter.kt
@@ -9,6 +9,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.dialogs.LyricsDialog
import code.name.monkey.retromusic.fragments.AlbumCoverStyle
import code.name.monkey.retromusic.fragments.NowPlayingScreen.*
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
@@ -90,6 +91,7 @@ class AlbumCoverPagerAdapter(
val view = inflater.inflate(getLayoutWithPlayerTheme(), container, false)
albumCover = view.findViewById(R.id.player_image)
albumCover.setOnClickListener {
+ LyricsDialog().show(childFragmentManager, "LyricsDialog")
showLyricsDialog()
}
return view
@@ -97,7 +99,7 @@ class AlbumCoverPagerAdapter(
private fun showLyricsDialog() {
lifecycleScope.launch(Dispatchers.IO) {
- val data = MusicUtil.getLyrics(song)
+ val data: String = MusicUtil.getLyrics(song) ?: "No lyrics found"
withContext(Dispatchers.Main) {
MaterialAlertDialogBuilder(
requireContext(),
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt
index 9b8dcb03d..8198a957e 100644
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/album/HorizontalAlbumAdapter.kt
@@ -3,7 +3,6 @@ package code.name.monkey.retromusic.adapter.album
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentActivity
-import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.retromusic.fragments.albums.AlbumClickListener
import code.name.monkey.retromusic.glide.AlbumGlideRequest
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
@@ -30,14 +29,14 @@ class HorizontalAlbumAdapter(
}
override fun setColors(color: MediaNotificationProcessor, holder: ViewHolder) {
- holder.title?.setTextColor(ATHUtil.resolveColor(activity, android.R.attr.textColorPrimary))
- holder.text?.setTextColor(ATHUtil.resolveColor(activity, android.R.attr.textColorSecondary))
+ //holder.title?.setTextColor(ATHUtil.resolveColor(activity, android.R.attr.textColorPrimary))
+ //holder.text?.setTextColor(ATHUtil.resolveColor(activity, android.R.attr.textColorSecondary))
}
override fun loadAlbumCover(album: Album, holder: ViewHolder) {
if (holder.image == null) return
AlbumGlideRequest.Builder.from(Glide.with(activity), album.safeGetFirstSong())
- .checkIgnoreMediaStore(activity)
+ .checkIgnoreMediaStore()
.generatePalette(activity)
.build()
.into(object : RetroMusicColoredTarget(holder.image!!) {
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/LegacyPlaylistAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/LegacyPlaylistAdapter.kt
new file mode 100644
index 000000000..c74c8a5f9
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/LegacyPlaylistAdapter.kt
@@ -0,0 +1,52 @@
+package code.name.monkey.retromusic.adapter.playlist
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.FragmentActivity
+import androidx.recyclerview.widget.RecyclerView
+import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
+import code.name.monkey.retromusic.model.Playlist
+import code.name.monkey.retromusic.util.MusicUtil
+
+class LegacyPlaylistAdapter(
+ private val activity: FragmentActivity,
+ private var list: List,
+ private val layoutRes: Int,
+ private val playlistClickListener: PlaylistClickListener
+) :
+ RecyclerView.Adapter() {
+
+ fun swapData(list: List) {
+ this.list = list
+ notifyDataSetChanged()
+ }
+
+ class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView)
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(parent.context).inflate(layoutRes, parent, false)
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val playlist: Playlist = list[position]
+ holder.title?.text = playlist.name
+ holder.text?.text = MusicUtil.getPlaylistInfoString(activity, playlist.getSongs())
+ holder.itemView.setOnClickListener {
+ playlistClickListener.onPlaylistClick(playlist)
+ }
+ }
+
+ override fun getItemCount(): Int {
+ return list.size
+ }
+
+ interface PlaylistClickListener {
+ fun onPlaylistClick(playlist: Playlist)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt
index 39d4f8e10..1d21b8036 100755
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/playlist/PlaylistAdapter.kt
@@ -13,51 +13,50 @@ import androidx.appcompat.widget.PopupMenu
import androidx.core.os.bundleOf
import androidx.fragment.app.FragmentActivity
import androidx.navigation.findNavController
-import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.base.AbsMultiSelectAdapter
import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder
+import code.name.monkey.retromusic.db.PlaylistEntity
+import code.name.monkey.retromusic.db.PlaylistWithSongs
+import code.name.monkey.retromusic.db.SongEntity
+import code.name.monkey.retromusic.db.toSongs
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
import code.name.monkey.retromusic.helper.menu.SongsMenuHelper
import code.name.monkey.retromusic.interfaces.CabHolder
-import code.name.monkey.retromusic.model.AbsCustomPlaylist
import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.model.smartplaylist.AbsSmartPlaylist
import code.name.monkey.retromusic.repository.PlaylistSongsLoader
import code.name.monkey.retromusic.util.AutoGeneratedPlaylistBitmap
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.RetroColorUtil
-import java.util.*
class PlaylistAdapter(
private val activity: FragmentActivity,
- var dataSet: List,
+ var dataSet: List,
private var itemLayoutRes: Int,
cabHolder: CabHolder?
-) : AbsMultiSelectAdapter(
+) : AbsMultiSelectAdapter(
activity,
cabHolder,
R.menu.menu_playlists_selection
) {
-
init {
setHasStableIds(true)
}
- fun swapDataSet(dataSet: List) {
+ fun swapDataSet(dataSet: List) {
this.dataSet = dataSet
notifyDataSetChanged()
}
override fun getItemId(position: Int): Long {
- return dataSet[position].id.toLong()
+ return dataSet[position].playlistEntity.playListId.toLong()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
@@ -69,20 +68,20 @@ class PlaylistAdapter(
return ViewHolder(view)
}
- private fun getPlaylistTitle(playlist: Playlist): String {
- return if (TextUtils.isEmpty(playlist.name)) "-" else playlist.name
+ private fun getPlaylistTitle(playlist: PlaylistEntity): String {
+ return if (TextUtils.isEmpty(playlist.playlistName)) "-" else playlist.playlistName
}
- private fun getPlaylistText(playlist: Playlist): String {
- return MusicUtil.getPlaylistInfoString(activity, getSongs(playlist))
+ private fun getPlaylistText(playlist: PlaylistWithSongs): String {
+ return MusicUtil.getPlaylistInfoString(activity, playlist.songs.toSongs())
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val playlist = dataSet[position]
holder.itemView.isActivated = isChecked(playlist)
- holder.title?.text = getPlaylistTitle(playlist)
+ holder.title?.text = getPlaylistTitle(playlist.playlistEntity)
holder.text?.text = getPlaylistText(playlist)
- holder.image?.setImageDrawable(getIconRes(playlist))
+ holder.image?.setImageDrawable(getIconRes())
val isChecked = isChecked(playlist)
if (isChecked) {
holder.menu?.hide()
@@ -92,37 +91,25 @@ class PlaylistAdapter(
//PlaylistBitmapLoader(this, holder, playlist).execute()
}
- private fun getIconRes(playlist: Playlist): Drawable {
- return if (MusicUtil.isFavoritePlaylist(activity, playlist))
- TintHelper.createTintedDrawable(
- activity,
- R.drawable.ic_favorite,
- ThemeStore.accentColor(activity)
- )
- else TintHelper.createTintedDrawable(
- activity,
- R.drawable.ic_playlist_play,
- ATHUtil.resolveColor(activity, R.attr.colorControlNormal)
- )
- }
-
- override fun getItemViewType(position: Int): Int {
- return if (dataSet[position] is AbsSmartPlaylist) SMART_PLAYLIST else DEFAULT_PLAYLIST
- }
+ private fun getIconRes(): Drawable = TintHelper.createTintedDrawable(
+ activity,
+ R.drawable.ic_playlist_play,
+ ATHUtil.resolveColor(activity, R.attr.colorControlNormal)
+ )
override fun getItemCount(): Int {
return dataSet.size
}
- override fun getIdentifier(position: Int): Playlist? {
+ override fun getIdentifier(position: Int): PlaylistWithSongs? {
return dataSet[position]
}
- override fun getName(playlist: Playlist): String {
- return playlist.name
+ override fun getName(playlist: PlaylistWithSongs): String {
+ return playlist.playlistEntity.playlistName
}
- override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
+ override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
when (menuItem.itemId) {
else -> SongsMenuHelper.handleMenuClick(
activity,
@@ -132,37 +119,26 @@ class PlaylistAdapter(
}
}
- private fun getSongList(playlists: List): List {
- val songs = ArrayList()
- for (playlist in playlists) {
- if (playlist is AbsCustomPlaylist) {
- songs.addAll(playlist.songs())
- } else {
- songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id))
- }
+ private fun getSongList(playlists: List): List {
+ val songs = mutableListOf()
+ playlists.forEach {
+ songs.addAll(it.songs.toSongs())
}
return songs
}
- private fun getSongs(playlist: Playlist): List {
- val songs = ArrayList()
- if (playlist is AbsSmartPlaylist) {
- songs.addAll(playlist.songs())
- } else {
- songs.addAll(playlist.getSongs())
+ private fun getSongs(playlist: PlaylistWithSongs): List =
+ mutableListOf().apply {
+ addAll(playlist.songs)
}
- return songs
- }
inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) {
init {
-
image?.apply {
val iconPadding =
activity.resources.getDimensionPixelSize(R.dimen.list_item_image_icon_padding)
setPadding(iconPadding, iconPadding, iconPadding, iconPadding)
}
-
menu?.setOnClickListener { view ->
val popupMenu = PopupMenu(activity, view)
popupMenu.inflate(R.menu.menu_item_playlist)
@@ -221,7 +197,5 @@ class PlaylistAdapter(
companion object {
val TAG: String = PlaylistAdapter::class.java.simpleName
- private const val SMART_PLAYLIST = 0
- private const val DEFAULT_PLAYLIST = 1
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt
index 2b3ccc3c8..6407a626b 100644
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/OrderablePlaylistSongAdapter.kt
@@ -5,7 +5,9 @@ import android.view.View
import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.R.menu
-import code.name.monkey.retromusic.dialogs.RemoveFromPlaylistDialog
+import code.name.monkey.retromusic.db.PlaylistEntity
+import code.name.monkey.retromusic.db.toSongs
+import code.name.monkey.retromusic.dialogs.RemoveSongFromPlaylistDialog
import code.name.monkey.retromusic.interfaces.CabHolder
import code.name.monkey.retromusic.model.PlaylistSong
import code.name.monkey.retromusic.model.Song
@@ -16,6 +18,7 @@ import com.h6ah4i.android.widget.advrecyclerview.draggable.ItemDraggableRange
import com.h6ah4i.android.widget.advrecyclerview.draggable.annotation.DraggableItemStateFlags
class OrderablePlaylistSongAdapter(
+ private val playlist: PlaylistEntity,
activity: FragmentActivity,
dataSet: ArrayList,
itemLayoutRes: Int,
@@ -54,8 +57,8 @@ class OrderablePlaylistSongAdapter(
override fun onMultipleItemAction(menuItem: MenuItem, selection: List) {
when (menuItem.itemId) {
R.id.action_remove_from_playlist -> {
- RemoveFromPlaylistDialog.create(selection as ArrayList)
- .show(activity.supportFragmentManager, "ADD_PLAYLIST")
+ RemoveSongFromPlaylistDialog.create(selection.toSongs(playlist.playListId))
+ .show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
return
}
}
@@ -118,7 +121,7 @@ class OrderablePlaylistSongAdapter(
override fun onSongMenuItemClick(item: MenuItem): Boolean {
when (item.itemId) {
R.id.action_remove_from_playlist -> {
- RemoveFromPlaylistDialog.create(song as PlaylistSong)
+ RemoveSongFromPlaylistDialog.create(song.toSongEntity(playlist.playListId))
.show(activity.supportFragmentManager, "REMOVE_FROM_PLAYLIST")
return true
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt
index b699b39cb..2b1b9198a 100644
--- a/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/adapter/song/PlayingQueueAdapter.kt
@@ -20,7 +20,6 @@ import com.h6ah4i.android.widget.advrecyclerview.swipeable.SwipeableItemConstant
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultAction
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionDefault
import com.h6ah4i.android.widget.advrecyclerview.swipeable.action.SwipeResultActionRemoveItem
-import com.h6ah4i.android.widget.advrecyclerview.swipeable.annotation.SwipeableItemResults
import me.zhanghai.android.fastscroll.PopupTextProvider
class PlayingQueueAdapter(
@@ -153,8 +152,8 @@ class PlayingQueueAdapter(
mDragStateFlags = flags
}
- override fun getSwipeableContainerView(): View? {
- return dummyContainer
+ override fun getSwipeableContainerView(): View {
+ return dummyContainer!!
}
}
@@ -165,18 +164,15 @@ class PlayingQueueAdapter(
private const val UP_NEXT = 2
}
- override fun onSwipeItem(
- holder: ViewHolder?,
- position: Int, @SwipeableItemResults result: Int
- ): SwipeResultAction {
- return if (result === SwipeableItemConstants.RESULT_CANCELED) {
+ override fun onSwipeItem(holder: ViewHolder, position: Int, result: Int): SwipeResultAction? {
+ return if (result == SwipeableItemConstants.RESULT_CANCELED) {
SwipeResultActionDefault()
} else {
SwipedResultActionRemoveItem(this, position, activity)
}
}
- override fun onGetSwipeReactionType(holder: ViewHolder?, position: Int, x: Int, y: Int): Int {
+ override fun onGetSwipeReactionType(holder: ViewHolder, position: Int, x: Int, y: Int): Int {
return if (onCheckCanStartDrag(holder!!, position, x, y)) {
SwipeableItemConstants.REACTION_CAN_NOT_SWIPE_BOTH_H
} else {
@@ -184,10 +180,10 @@ class PlayingQueueAdapter(
}
}
- override fun onSwipeItemStarted(p0: ViewHolder?, p1: Int) {
+ override fun onSwipeItemStarted(holder: ViewHolder, p1: Int) {
}
- override fun onSetSwipeBackground(holder: ViewHolder?, position: Int, result: Int) {
+ override fun onSetSwipeBackground(holder: ViewHolder, position: Int, result: Int) {
}
internal class SwipedResultActionRemoveItem(
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreDao.kt
new file mode 100644
index 000000000..db0dd0f64
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreDao.kt
@@ -0,0 +1,21 @@
+package code.name.monkey.retromusic.db
+
+import androidx.room.*
+
+@Dao
+interface BlackListStoreDao {
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun insertBlacklistPath(blackListStoreEntity: BlackListStoreEntity)
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun insertBlacklistPath(blackListStoreEntities: List)
+
+ @Delete
+ suspend fun deleteBlacklistPath(blackListStoreEntity: BlackListStoreEntity)
+
+ @Query("DELETE FROM BlackListStoreEntity")
+ suspend fun clearBlacklist()
+
+ @Query("SELECT * FROM BlackListStoreEntity")
+ fun blackListPaths(): List
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreEntity.kt
new file mode 100644
index 000000000..5ccbce07c
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/BlackListStoreEntity.kt
@@ -0,0 +1,10 @@
+package code.name.monkey.retromusic.db
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity
+class BlackListStoreEntity(
+ @PrimaryKey
+ val path: String
+)
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/HistoryDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/HistoryDao.kt
new file mode 100644
index 000000000..5ea731a2f
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/HistoryDao.kt
@@ -0,0 +1,26 @@
+package code.name.monkey.retromusic.db
+
+import androidx.lifecycle.LiveData
+import androidx.room.*
+
+@Dao
+interface HistoryDao {
+ companion object {
+ private const val HISTORY_LIMIT = 100
+ }
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun insertSongInHistory(historyEntity: HistoryEntity)
+
+ @Query("SELECT * FROM HistoryEntity WHERE id = :songId LIMIT 1")
+ suspend fun isSongPresentInHistory(songId: Int): HistoryEntity?
+
+ @Update
+ suspend fun updateHistorySong(historyEntity: HistoryEntity)
+
+ @Query("SELECT * FROM HistoryEntity ORDER BY time_played DESC LIMIT $HISTORY_LIMIT")
+ fun historySongs(): List
+
+ @Query("SELECT * FROM HistoryEntity ORDER BY time_played DESC LIMIT $HISTORY_LIMIT")
+ fun observableHistorySongs(): LiveData>
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/HistoryEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/HistoryEntity.kt
new file mode 100644
index 000000000..bbb2471fb
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/HistoryEntity.kt
@@ -0,0 +1,32 @@
+package code.name.monkey.retromusic.db
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity
+class HistoryEntity(
+ @PrimaryKey
+ val id: Int,
+ val title: String,
+ @ColumnInfo(name = "track_number")
+ val trackNumber: Int,
+ val year: Int,
+ val duration: Long,
+ val data: String,
+ @ColumnInfo(name = "date_modified")
+ val dateModified: Long,
+ @ColumnInfo(name = "album_id")
+ val albumId: Int,
+ @ColumnInfo(name = "album_name")
+ val albumName: String,
+ @ColumnInfo(name = "artist_id")
+ val artistId: Int,
+ @ColumnInfo(name = "artist_name")
+ val artistName: String,
+ val composer: String?,
+ @ColumnInfo(name = "album_artist")
+ val albumArtist: String?,
+ @ColumnInfo(name = "time_played")
+ val timePlayed: Long
+)
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/LyricsDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/LyricsDao.kt
new file mode 100644
index 000000000..a09b430a2
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/LyricsDao.kt
@@ -0,0 +1,18 @@
+package code.name.monkey.retromusic.db
+
+import androidx.room.*
+
+@Dao
+interface LyricsDao {
+ @Query("SELECT * FROM LyricsEntity WHERE songId =:songId LIMIT 1")
+ fun lyricsWithSongId(songId: Int): LyricsEntity?
+
+ @Insert
+ fun insertLyrics(lyricsEntity: LyricsEntity)
+
+ @Delete
+ fun deleteLyrics(lyricsEntity: LyricsEntity)
+
+ @Update
+ fun updateLyrics(lyricsEntity: LyricsEntity)
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/LyricsEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/LyricsEntity.kt
new file mode 100644
index 000000000..0cec6431c
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/LyricsEntity.kt
@@ -0,0 +1,10 @@
+package code.name.monkey.retromusic.db
+
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity
+class LyricsEntity(
+ @PrimaryKey val songId: Int,
+ val lyrics: String
+)
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlayCountDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlayCountDao.kt
new file mode 100644
index 000000000..0c3fbbaed
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/PlayCountDao.kt
@@ -0,0 +1,27 @@
+package code.name.monkey.retromusic.db
+
+import androidx.room.*
+
+@Dao
+interface PlayCountDao {
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ fun insertSongInPlayCount(playCountEntity: PlayCountEntity)
+
+ @Update
+ fun updateSongInPlayCount(playCountEntity: PlayCountEntity)
+
+ @Delete
+ fun deleteSongInPlayCount(playCountEntity: PlayCountEntity)
+
+ @Query("SELECT * FROM PlayCountEntity WHERE id =:songId")
+ fun checkSongExistInPlayCount(songId: Int): List
+
+ @Query("SELECT * FROM PlayCountEntity ORDER BY play_count DESC")
+ fun playCountSongs(): List
+
+ @Query("DELETE FROM SongEntity WHERE id =:songId")
+ fun deleteSong(songId: Int)
+
+ @Query("UPDATE PlayCountEntity SET play_count = play_count + 1 WHERE id = :id")
+ fun updateQuantity(id: Int)
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlayCountEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlayCountEntity.kt
new file mode 100644
index 000000000..94d496d4d
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/PlayCountEntity.kt
@@ -0,0 +1,34 @@
+package code.name.monkey.retromusic.db
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity
+class PlayCountEntity(
+ @PrimaryKey
+ val id: Int,
+ val title: String,
+ @ColumnInfo(name = "track_number")
+ val trackNumber: Int,
+ val year: Int,
+ val duration: Long,
+ val data: String,
+ @ColumnInfo(name = "date_modified")
+ val dateModified: Long,
+ @ColumnInfo(name = "album_id")
+ val albumId: Int,
+ @ColumnInfo(name = "album_name")
+ val albumName: String,
+ @ColumnInfo(name = "artist_id")
+ val artistId: Int,
+ @ColumnInfo(name = "artist_name")
+ val artistName: String,
+ val composer: String?,
+ @ColumnInfo(name = "album_artist")
+ val albumArtist: String?,
+ @ColumnInfo(name = "time_played")
+ val timePlayed: Long,
+ @ColumnInfo(name = "play_count")
+ var playCount: Int
+)
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt
new file mode 100644
index 000000000..219ca590d
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistDao.kt
@@ -0,0 +1,56 @@
+package code.name.monkey.retromusic.db
+
+import androidx.lifecycle.LiveData
+import androidx.room.*
+
+@Dao
+interface PlaylistDao {
+ @Insert
+ suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long
+
+ @Query("UPDATE PlaylistEntity SET playlist_name = :name WHERE playlist_id = :playlistId")
+ suspend fun renamePlaylist(playlistId: Int, name: String)
+
+ @Query("SELECT * FROM PlaylistEntity WHERE playlist_name = :name")
+ fun isPlaylistExists(name: String): List
+
+ @Query("SELECT * FROM PlaylistEntity")
+ suspend fun playlists(): List
+
+ @Query("DELETE FROM SongEntity WHERE playlist_creator_id = :playlistId")
+ suspend fun deletePlaylistSongs(playlistId: Int)
+
+ @Query("DELETE FROM SongEntity WHERE playlist_creator_id = :playlistId AND id = :songId")
+ suspend fun deleteSongFromPlaylist(playlistId: Int, songId: Int)
+
+ @Transaction
+ @Query("SELECT * FROM PlaylistEntity")
+ suspend fun playlistsWithSongs(): List
+
+ @Insert(onConflict = OnConflictStrategy.REPLACE)
+ suspend fun insertSongsToPlaylist(songEntities: List)
+
+ @Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistId AND id = :songId")
+ suspend fun isSongExistsInPlaylist(playlistId: Int, songId: Int): List
+
+ @Query("SELECT * FROM SongEntity WHERE playlist_creator_id = :playlistId")
+ fun songsFromPlaylist(playlistId: Int): LiveData>
+
+ @Delete
+ suspend fun deletePlaylist(playlistEntity: PlaylistEntity)
+
+ @Delete
+ suspend fun deletePlaylists(playlistEntities: List)
+
+ @Delete
+ suspend fun deletePlaylistSongs(songs: List)
+
+
+ @Query("SELECT * FROM SongEntity WHERE playlist_creator_id= :playlistId")
+ fun favoritesSongsLiveData(playlistId: Int): LiveData>
+
+ @Query("SELECT * FROM SongEntity WHERE playlist_creator_id= :playlistId")
+ fun favoritesSongs(playlistId: Int): List
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistEntity.kt
new file mode 100644
index 000000000..3bb1681f2
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistEntity.kt
@@ -0,0 +1,18 @@
+package code.name.monkey.retromusic.db
+
+import android.os.Parcelable
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+import kotlinx.android.parcel.Parcelize
+
+@Entity
+@Parcelize
+class PlaylistEntity(
+ @ColumnInfo(name = "playlist_name")
+ val playlistName: String
+) : Parcelable {
+ @PrimaryKey(autoGenerate = true)
+ @ColumnInfo(name = "playlist_id")
+ var playListId: Int = 0
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/PlaylistWithSongs.kt b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistWithSongs.kt
new file mode 100644
index 000000000..5a256bde7
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/PlaylistWithSongs.kt
@@ -0,0 +1,17 @@
+package code.name.monkey.retromusic.db
+
+import android.os.Parcelable
+import androidx.room.Embedded
+import androidx.room.Relation
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+data class PlaylistWithSongs(
+ @Embedded val playlistEntity: PlaylistEntity,
+ @Relation(
+ parentColumn = "playlist_id",
+ entityColumn = "playlist_creator_id"
+ )
+ val songs: List
+) : Parcelable
+
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/RetroDatabase.kt b/app/src/main/java/code/name/monkey/retromusic/db/RetroDatabase.kt
new file mode 100644
index 000000000..6be545b6a
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/RetroDatabase.kt
@@ -0,0 +1,17 @@
+package code.name.monkey.retromusic.db
+
+import androidx.room.Database
+import androidx.room.RoomDatabase
+
+@Database(
+ entities = [PlaylistEntity::class, SongEntity::class, HistoryEntity::class, PlayCountEntity::class, BlackListStoreEntity::class, LyricsEntity::class],
+ version = 22,
+ exportSchema = false
+)
+abstract class RetroDatabase : RoomDatabase() {
+ abstract fun playlistDao(): PlaylistDao
+ abstract fun blackListStore(): BlackListStoreDao
+ abstract fun playCountDao(): PlayCountDao
+ abstract fun historyDao(): HistoryDao
+ abstract fun lyricsDao(): LyricsDao
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/SongEntity.kt b/app/src/main/java/code/name/monkey/retromusic/db/SongEntity.kt
new file mode 100644
index 000000000..19a50fe0f
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/SongEntity.kt
@@ -0,0 +1,40 @@
+package code.name.monkey.retromusic.db
+
+import android.os.Parcelable
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.Index
+import androidx.room.PrimaryKey
+import kotlinx.android.parcel.Parcelize
+
+@Parcelize
+@Entity(indices = [Index(value = ["playlist_creator_id", "id"], unique = true)])
+class SongEntity(
+ @ColumnInfo(name = "playlist_creator_id")
+ val playlistCreatorId: Int,
+ val id: Int,
+ val title: String,
+ @ColumnInfo(name = "track_number")
+ val trackNumber: Int,
+ val year: Int,
+ val duration: Long,
+ val data: String,
+ @ColumnInfo(name = "date_modified")
+ val dateModified: Long,
+ @ColumnInfo(name = "album_id")
+ val albumId: Int,
+ @ColumnInfo(name = "album_name")
+ val albumName: String,
+ @ColumnInfo(name = "artist_id")
+ val artistId: Int,
+ @ColumnInfo(name = "artist_name")
+ val artistName: String,
+ val composer: String?,
+ @ColumnInfo(name = "album_artist")
+ val albumArtist: String?
+) : Parcelable {
+ @PrimaryKey(autoGenerate = true)
+ @ColumnInfo(name = "song_key")
+ var songPrimaryKey: Long = 0
+}
+
diff --git a/app/src/main/java/code/name/monkey/retromusic/db/SongExtension.kt b/app/src/main/java/code/name/monkey/retromusic/db/SongExtension.kt
new file mode 100644
index 000000000..d5f009e01
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/db/SongExtension.kt
@@ -0,0 +1,95 @@
+package code.name.monkey.retromusic.db
+
+import code.name.monkey.retromusic.model.Song
+
+fun List.toSongs(): List {
+ return map {
+ it.toSong()
+ }
+}
+
+fun List.toSongs(playlistId: Int): List {
+ return map {
+ it.toSongEntity(playlistId)
+ }
+}
+
+fun SongEntity.toSong(): Song {
+ return Song(
+ id,
+ title,
+ trackNumber,
+ year,
+ duration,
+ data,
+ dateModified,
+ albumId,
+ albumName,
+ artistId,
+ artistName,
+ composer,
+ albumArtist
+ )
+}
+
+fun PlayCountEntity.toSong(): Song {
+ return Song(
+ id,
+ title,
+ trackNumber,
+ year,
+ duration,
+ data,
+ dateModified,
+ albumId,
+ albumName,
+ artistId,
+ artistName,
+ composer,
+ albumArtist
+ )
+}
+
+fun HistoryEntity.toSong(): Song {
+ return Song(
+ id,
+ title,
+ trackNumber,
+ year,
+ duration,
+ data,
+ dateModified,
+ albumId,
+ albumName,
+ artistId,
+ artistName,
+ composer,
+ albumArtist
+ )
+}
+
+fun Song.toPlayCount(): PlayCountEntity {
+ return PlayCountEntity(
+ id,
+ title,
+ trackNumber,
+ year,
+ duration,
+ data,
+ dateModified,
+ albumId,
+ albumName,
+ artistId,
+ artistName,
+ composer,
+ albumArtist,
+ System.currentTimeMillis(),
+ 1
+ )
+}
+
+fun List.toSongsEntity(playlistEntity: PlaylistEntity): List {
+ return map {
+ it.toSongEntity(playlistEntity.playListId)
+ }
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt
index c4d54ef0e..53acaa254 100644
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/AddToPlaylistDialog.kt
@@ -1,77 +1,70 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
package code.name.monkey.retromusic.dialogs
import android.app.Dialog
import android.os.Bundle
+import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
+import androidx.lifecycle.lifecycleScope
+import code.name.monkey.retromusic.EXTRA_PLAYLISTS
import code.name.monkey.retromusic.EXTRA_SONG
import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.db.PlaylistEntity
+import code.name.monkey.retromusic.db.SongEntity
+import code.name.monkey.retromusic.db.toSongsEntity
import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
+import code.name.monkey.retromusic.fragments.LibraryViewModel
+import code.name.monkey.retromusic.fragments.ReloadType.Playlists
import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.repository.PlaylistRepository
-import code.name.monkey.retromusic.util.PlaylistsUtil
-import org.koin.android.ext.android.inject
-
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class AddToPlaylistDialog : DialogFragment() {
- private val playlistRepository by inject()
- override fun onCreateDialog(
- savedInstanceState: Bundle?
- ): Dialog {
- val playlists = playlistRepository.playlists()
- val playlistNames = mutableListOf()
+ private val libraryViewModel by sharedViewModel()
+
+ companion object {
+ fun create(playlistEntities: List, song: Song): AddToPlaylistDialog {
+ val list: MutableList = mutableListOf()
+ list.add(song)
+ return create(playlistEntities, list)
+ }
+
+ fun create(playlistEntities: List, songs: List): AddToPlaylistDialog {
+ return AddToPlaylistDialog().apply {
+ arguments = bundleOf(
+ EXTRA_SONG to songs,
+ EXTRA_PLAYLISTS to playlistEntities
+ )
+ }
+ }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val playlistEntities: List =
+ extraNotNull>(EXTRA_PLAYLISTS).value
+ val songs: List = extraNotNull>(EXTRA_SONG).value
+ val playlistNames: MutableList = mutableListOf()
playlistNames.add(requireContext().resources.getString(R.string.action_new_playlist))
- for (p in playlists) {
- playlistNames.add(p.name)
+ for (entity: PlaylistEntity in playlistEntities) {
+ playlistNames.add(entity.playlistName)
}
return materialDialog(R.string.add_playlist_title)
.setItems(playlistNames.toTypedArray()) { _, which ->
- val songs = extraNotNull>(EXTRA_SONG).value
if (which == 0) {
CreatePlaylistDialog.create(songs)
- .show(requireActivity().supportFragmentManager, "ADD_TO_PLAYLIST")
+ .show(requireActivity().supportFragmentManager, "Dialog")
} else {
- PlaylistsUtil.addToPlaylist(
- requireContext(),
- songs,
- playlists[which - 1].id,
- true
- )
+ lifecycleScope.launch(Dispatchers.IO) {
+ val songEntities: List =
+ songs.toSongsEntity(playlistEntities[which - 1])
+ libraryViewModel.insertSongs(songEntities)
+ libraryViewModel.forceReload(Playlists)
+ }
}
dismiss()
}
.create().colorButtons()
}
-
- companion object {
-
- fun create(song: Song): AddToPlaylistDialog {
- val list = ArrayList()
- list.add(song)
- return create(list)
- }
-
- fun create(songs: List): AddToPlaylistDialog {
- val dialog = AddToPlaylistDialog()
- val args = Bundle()
- args.putParcelableArrayList(EXTRA_SONG, ArrayList(songs))
- dialog.arguments = args
- return dialog
- }
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt
index d4eeb9eb3..db5158ae1 100644
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/CreatePlaylistDialog.kt
@@ -1,88 +1,74 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
package code.name.monkey.retromusic.dialogs
-import android.annotation.SuppressLint
import android.app.Dialog
import android.os.Bundle
import android.text.TextUtils
import android.view.LayoutInflater
+import android.widget.Toast
+import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
-import code.name.monkey.appthemehelper.util.MaterialUtil
+import androidx.lifecycle.lifecycleScope
import code.name.monkey.retromusic.EXTRA_SONG
import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.extensions.colorButtons
-import code.name.monkey.retromusic.extensions.extraNotNull
+import code.name.monkey.retromusic.extensions.extra
import code.name.monkey.retromusic.extensions.materialDialog
+import code.name.monkey.retromusic.fragments.LibraryViewModel
+import code.name.monkey.retromusic.fragments.ReloadType.Playlists
import code.name.monkey.retromusic.model.Song
-import code.name.monkey.retromusic.util.PlaylistsUtil
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
import kotlinx.android.synthetic.main.dialog_playlist.view.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class CreatePlaylistDialog : DialogFragment() {
+ private val libraryViewModel by sharedViewModel()
- @SuppressLint("InflateParams")
- override fun onCreateDialog(
- savedInstanceState: Bundle?
- ): Dialog {
+ companion object {
+ fun create(song: Song): CreatePlaylistDialog {
+ val list = mutableListOf()
+ list.add(song)
+ return create(list)
+ }
+
+ fun create(songs: List): CreatePlaylistDialog {
+ return CreatePlaylistDialog().apply {
+ arguments = bundleOf(EXTRA_SONG to songs)
+ }
+ }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val view = LayoutInflater.from(requireActivity()).inflate(R.layout.dialog_playlist, null)
+ val songs: List = extra>(EXTRA_SONG).value ?: emptyList()
val playlistView: TextInputEditText = view.actionNewPlaylist
val playlistContainer: TextInputLayout = view.actionNewPlaylistContainer
- MaterialUtil.setTint(playlistContainer, false)
-
return materialDialog(R.string.new_playlist_title)
.setView(view)
- .setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(
R.string.create_action
) { _, _ ->
- val extra = extraNotNull>(EXTRA_SONG)
val playlistName = playlistView.text.toString()
if (!TextUtils.isEmpty(playlistName)) {
- val playlistId = PlaylistsUtil.createPlaylist(
- requireContext(),
- playlistView.text.toString()
- )
- if (playlistId != -1) {
- PlaylistsUtil.addToPlaylist(requireContext(), extra.value, playlistId, true)
+ lifecycleScope.launch(Dispatchers.IO) {
+ if (libraryViewModel.checkPlaylistExists(playlistName).isEmpty()) {
+ val playlistId: Long =
+ libraryViewModel.createPlaylist(PlaylistEntity(playlistName))
+ libraryViewModel.insertSongs(songs.map { it.toSongEntity(playlistId.toInt()) })
+ libraryViewModel.forceReload(Playlists)
+ } else {
+ Toast.makeText(requireContext(), "Playlist exists", Toast.LENGTH_SHORT)
+ .show()
+ }
}
+ } else {
+ playlistContainer.error = "Playlist is can't be empty"
}
}
.create()
.colorButtons()
}
-
- companion object {
- @JvmOverloads
- @JvmStatic
- fun create(song: Song? = null): CreatePlaylistDialog {
- val list = ArrayList()
- if (song != null) {
- list.add(song)
- }
- return create(list)
- }
-
- @JvmStatic
- fun create(songs: ArrayList): CreatePlaylistDialog {
- val dialog = CreatePlaylistDialog()
- val args = Bundle()
- args.putParcelableArrayList(EXTRA_SONG, songs)
- dialog.arguments = args
- return dialog
- }
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.kt
index 7a548de43..1ee8953ae 100644
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeletePlaylistDialog.kt
@@ -1,35 +1,41 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
package code.name.monkey.retromusic.dialogs
import android.app.Dialog
import android.os.Bundle
+import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import code.name.monkey.retromusic.EXTRA_PLAYLIST
import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
-import code.name.monkey.retromusic.model.Playlist
-import code.name.monkey.retromusic.util.PlaylistsUtil
+import code.name.monkey.retromusic.fragments.LibraryViewModel
+import code.name.monkey.retromusic.fragments.ReloadType
+import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class DeletePlaylistDialog : DialogFragment() {
+ private val libraryViewModel by sharedViewModel()
+
+ companion object {
+
+ fun create(playlist: PlaylistEntity): DeletePlaylistDialog {
+ val list = mutableListOf()
+ list.add(playlist)
+ return create(list)
+ }
+
+ fun create(playlists: List): DeletePlaylistDialog {
+ return DeletePlaylistDialog().apply {
+ arguments = bundleOf(EXTRA_PLAYLIST to playlists)
+ }
+ }
+ }
+
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val playlists = extraNotNull>(EXTRA_PLAYLIST).value
+ val playlists = extraNotNull>(EXTRA_PLAYLIST).value
val title: Int
val message: CharSequence
//noinspection ConstantConditions
@@ -42,7 +48,7 @@ class DeletePlaylistDialog : DialogFragment() {
} else {
title = R.string.delete_playlist_title
message = HtmlCompat.fromHtml(
- String.format(getString(R.string.delete_playlist_x), playlists[0].name),
+ String.format(getString(R.string.delete_playlist_x), playlists[0].playlistName),
HtmlCompat.FROM_HTML_MODE_LEGACY
)
}
@@ -52,26 +58,12 @@ class DeletePlaylistDialog : DialogFragment() {
.setMessage(message)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.action_delete) { _, _ ->
- PlaylistsUtil.deletePlaylists(requireContext(), playlists)
+ libraryViewModel.deleteSongsFromPlaylist(playlists)
+ libraryViewModel.deleteRoomPlaylist(playlists)
+ libraryViewModel.forceReload(ReloadType.Playlists)
}
.create()
.colorButtons()
}
- companion object {
-
- fun create(playlist: Playlist): DeletePlaylistDialog {
- val list = ArrayList()
- list.add(playlist)
- return create(list)
- }
-
- fun create(playlist: ArrayList): DeletePlaylistDialog {
- val dialog = DeletePlaylistDialog()
- val args = Bundle()
- args.putParcelableArrayList(EXTRA_PLAYLIST, playlist)
- dialog.arguments = args
- return dialog
- }
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsAsyncTask.java b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsAsyncTask.java
deleted file mode 100644
index 5cc00d765..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsAsyncTask.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package code.name.monkey.retromusic.dialogs;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.FragmentActivity;
-
-import com.google.android.material.dialog.MaterialAlertDialogBuilder;
-
-import java.lang.ref.WeakReference;
-import java.util.Collections;
-import java.util.List;
-
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.activities.saf.SAFGuideActivity;
-import code.name.monkey.retromusic.misc.DialogAsyncTask;
-import code.name.monkey.retromusic.model.Song;
-import code.name.monkey.retromusic.util.SAFUtil;
-
-/**
- * Created by hemanths on 2019-07-31.
- */
-public class DeleteSongsAsyncTask extends DialogAsyncTask {
-
- private WeakReference activityWeakReference;
- private WeakReference dialogReference;
-
- public DeleteSongsAsyncTask(@NonNull DeleteSongsDialog dialog) {
- super(dialog.getActivity());
- this.dialogReference = new WeakReference<>(dialog);
- this.activityWeakReference = new WeakReference<>(dialog.getActivity());
- }
-
- @NonNull
- @Override
- protected Dialog createDialog(@NonNull Context context) {
- return new MaterialAlertDialogBuilder(context,
- R.style.ThemeOverlay_MaterialComponents_Dialog_Alert)
- .setTitle(R.string.deleting_songs)
- .setView(R.layout.loading)
- .setCancelable(false)
- .create();
- }
-
- @Nullable
- @Override
- protected Void doInBackground(@NonNull LoadingInfo... loadingInfos) {
- try {
- LoadingInfo info = loadingInfos[0];
- DeleteSongsDialog dialog = this.dialogReference.get();
- FragmentActivity fragmentActivity = this.activityWeakReference.get();
-
- if (dialog == null || fragmentActivity == null) {
- return null;
- }
-
- if (!info.isIntent) {
- if (!SAFUtil.isSAFRequiredForSongs(info.songs)) {
- dialog.deleteSongs(info.songs, null);
- } else {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
- if (SAFUtil.isSDCardAccessGranted(fragmentActivity)) {
- dialog.deleteSongs(info.songs, null);
- } else {
- dialog.startActivityForResult(new Intent(fragmentActivity, SAFGuideActivity.class),
- SAFGuideActivity.REQUEST_CODE_SAF_GUIDE);
- }
- } else {
- Log.i("Hmm", "doInBackground: kitkat delete songs");
- }
- }
- } else {
- switch (info.requestCode) {
- case SAFUtil.REQUEST_SAF_PICK_TREE:
- if (info.resultCode == Activity.RESULT_OK) {
- SAFUtil.saveTreeUri(fragmentActivity, info.intent);
- if (dialog.songsToRemove != null) {
- dialog.deleteSongs(dialog.songsToRemove, null);
- }
- }
- break;
- case SAFUtil.REQUEST_SAF_PICK_FILE:
- if (info.resultCode == Activity.RESULT_OK) {
- dialog.deleteSongs(Collections.singletonList(dialog.currentSong),
- Collections.singletonList(info.intent.getData()));
- }
- break;
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
-
- return null;
- }
-
- public static class LoadingInfo {
-
- public Intent intent;
-
- public boolean isIntent;
-
- public int requestCode;
-
- public int resultCode;
-
- public List safUris;
-
- public List songs;
-
- public LoadingInfo(List songs, List safUris) {
- this.isIntent = false;
- this.songs = songs;
- this.safUris = safUris;
- }
-
- public LoadingInfo(int requestCode, int resultCode, Intent intent) {
- this.isIntent = true;
- this.requestCode = requestCode;
- this.resultCode = resultCode;
- this.intent = intent;
- }
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.kt
index 1765d2322..24a67a0f1 100644
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/DeleteSongsDialog.kt
@@ -1,110 +1,24 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
package code.name.monkey.retromusic.dialogs
import android.app.Dialog
-import android.content.Intent
-import android.net.Uri
import android.os.Bundle
import androidx.core.text.HtmlCompat
import androidx.fragment.app.DialogFragment
import code.name.monkey.retromusic.EXTRA_SONG
import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.activities.saf.SAFGuideActivity
import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
+import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.MusicUtil
-import code.name.monkey.retromusic.util.SAFUtil
+import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class DeleteSongsDialog : DialogFragment() {
- @JvmField
- var currentSong: Song? = null
-
- @JvmField
- var songsToRemove: List? = null
-
- private var deleteSongsAsyncTask: DeleteSongsAsyncTask? = null
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val songs = extraNotNull>(EXTRA_SONG).value
- var title = 0
- var message: CharSequence = ""
- if (songs.size > 1) {
- title = R.string.delete_songs_title
- message = HtmlCompat.fromHtml(
- String.format(getString(R.string.delete_x_songs), songs.size),
- HtmlCompat.FROM_HTML_MODE_LEGACY
- )
- } else {
- title = R.string.delete_song_title
- message = HtmlCompat.fromHtml(
- String.format(getString(R.string.delete_song_x), songs[0].title),
- HtmlCompat.FROM_HTML_MODE_LEGACY
- )
- }
-
- return materialDialog(title)
- .setMessage(message)
- .setCancelable(false)
- .setNegativeButton(android.R.string.cancel, null)
- .setPositiveButton(R.string.action_delete) { _, _ ->
- if ((songs.size == 1) && MusicPlayerRemote.isPlaying(songs[0])) {
- MusicPlayerRemote.playNextSong()
- }
- songsToRemove = songs
- deleteSongsAsyncTask = DeleteSongsAsyncTask(this@DeleteSongsDialog)
- deleteSongsAsyncTask?.execute(DeleteSongsAsyncTask.LoadingInfo(songs, null))
- }
- .create()
- .colorButtons()
- }
-
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- super.onActivityResult(requestCode, resultCode, data)
- when (requestCode) {
- SAFGuideActivity.REQUEST_CODE_SAF_GUIDE -> {
- SAFUtil.openTreePicker(this)
- }
- SAFUtil.REQUEST_SAF_PICK_TREE,
- SAFUtil.REQUEST_SAF_PICK_FILE -> {
- if (deleteSongsAsyncTask != null) {
- deleteSongsAsyncTask?.cancel(true)
- }
- deleteSongsAsyncTask = DeleteSongsAsyncTask(this)
- deleteSongsAsyncTask?.execute(
- DeleteSongsAsyncTask.LoadingInfo(
- requestCode,
- resultCode,
- data
- )
- )
- }
- }
- }
-
- fun deleteSongs(songs: List, safUris: List?) {
- MusicUtil.deleteTracks(requireActivity(), songs, safUris, Runnable {
- dismiss()
- })
- }
+ private val libraryViewModel by sharedViewModel()
companion object {
-
fun create(song: Song): DeleteSongsDialog {
val list = ArrayList()
list.add(song)
@@ -119,5 +33,38 @@ class DeleteSongsDialog : DialogFragment() {
return dialog
}
}
-}
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val songs = extraNotNull>(EXTRA_SONG).value
+ val pair = if (songs.size > 1) {
+ Pair(
+ R.string.delete_songs_title,
+ HtmlCompat.fromHtml(
+ String.format(getString(R.string.delete_x_songs), songs.size),
+ HtmlCompat.FROM_HTML_MODE_LEGACY
+ )
+ )
+ } else {
+ Pair(
+ R.string.delete_song_title,
+ HtmlCompat.fromHtml(
+ String.format(getString(R.string.delete_song_x), songs[0].title),
+ HtmlCompat.FROM_HTML_MODE_LEGACY
+ )
+ )
+ }
+
+ return materialDialog(pair.first)
+ .setMessage(pair.second)
+ .setCancelable(false)
+ .setPositiveButton(R.string.action_delete) { _, _ ->
+ if (songs.isNotEmpty() and (songs.size == 1) and MusicPlayerRemote.isPlaying(songs.first())) {
+ MusicPlayerRemote.playNextSong()
+ }
+ MusicUtil.deleteTracks(requireActivity(), songs)
+ libraryViewModel.deleteTracks(songs)
+ }
+ .create()
+ .colorButtons()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/ImportPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/ImportPlaylistDialog.kt
new file mode 100644
index 000000000..359ef1c5b
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/ImportPlaylistDialog.kt
@@ -0,0 +1,24 @@
+package code.name.monkey.retromusic.dialogs
+
+import android.app.Dialog
+import android.os.Bundle
+import androidx.fragment.app.DialogFragment
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.extensions.colorButtons
+import code.name.monkey.retromusic.extensions.materialDialog
+import code.name.monkey.retromusic.fragments.LibraryViewModel
+import org.koin.androidx.viewmodel.ext.android.sharedViewModel
+
+class ImportPlaylistDialog : DialogFragment() {
+ private val libraryViewModel by sharedViewModel()
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return materialDialog(R.string.import_playlist)
+ .setMessage(R.string.import_playlist_message)
+ .setPositiveButton(R.string.import_label) { _, _ ->
+ libraryViewModel.importPlaylists()
+ }
+ .create()
+ .colorButtons()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/LyricsDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/LyricsDialog.kt
new file mode 100644
index 000000000..9c3b63c78
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/LyricsDialog.kt
@@ -0,0 +1,60 @@
+package code.name.monkey.retromusic.dialogs
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.DialogFragment
+import androidx.lifecycle.lifecycleScope
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.extensions.accentTextColor
+import code.name.monkey.retromusic.extensions.hide
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
+import code.name.monkey.retromusic.network.Result
+import code.name.monkey.retromusic.repository.Repository
+import kotlinx.android.synthetic.main.lyrics_dialog.*
+import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.Dispatchers.Main
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import org.koin.android.ext.android.inject
+
+class LyricsDialog : DialogFragment() {
+ override fun getTheme(): Int {
+ return R.style.MaterialAlertDialogTheme
+ }
+
+ private val repository by inject()
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ return inflater.inflate(R.layout.lyrics_dialog, container, false)
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ val song = MusicPlayerRemote.currentSong
+ dialogTitle.text = song.title
+ syncedLyrics.accentTextColor()
+ lifecycleScope.launch(IO) {
+ val result: Result = repository.lyrics(
+ song.artistName,
+ song.title
+ )
+ withContext(Main) {
+
+ when (result) {
+ is Result.Error -> progressBar.hide()
+ is Result.Loading -> println("Loading")
+ is Result.Success -> {
+ progressBar.hide()
+ lyricsText.text = result.data
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveFromPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveFromPlaylistDialog.kt
deleted file mode 100644
index dc1933984..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveFromPlaylistDialog.kt
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package code.name.monkey.retromusic.dialogs
-
-import android.app.Dialog
-import android.os.Bundle
-import androidx.core.text.HtmlCompat
-import androidx.fragment.app.DialogFragment
-import code.name.monkey.retromusic.EXTRA_SONG
-import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.R.string
-import code.name.monkey.retromusic.extensions.colorButtons
-import code.name.monkey.retromusic.extensions.materialDialog
-import code.name.monkey.retromusic.model.PlaylistSong
-import code.name.monkey.retromusic.util.PlaylistsUtil
-
-class RemoveFromPlaylistDialog : DialogFragment() {
-
- override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val songs = requireArguments().getParcelableArrayList(EXTRA_SONG)
-
- var title = 0
- var message: CharSequence = ""
- if (songs != null) {
- if (songs.size > 1) {
- title = R.string.remove_songs_from_playlist_title
- message = HtmlCompat.fromHtml(
- String.format(getString(string.remove_x_songs_from_playlist), songs.size),
- HtmlCompat.FROM_HTML_MODE_LEGACY
- )
- } else {
- title = R.string.remove_song_from_playlist_title
- message = HtmlCompat.fromHtml(
- String.format(
- getString(string.remove_song_x_from_playlist),
- songs[0].title
- ),
- HtmlCompat.FROM_HTML_MODE_LEGACY
- )
- }
- }
-
- return materialDialog(title)
- .setMessage(message)
- .setPositiveButton(R.string.remove_action) { _, _ ->
- PlaylistsUtil.removeFromPlaylist(
- requireContext(),
- songs as MutableList
- )
- }
- .setNegativeButton(android.R.string.cancel, null)
- .create()
- .colorButtons()
- }
-
- companion object {
-
- fun create(song: PlaylistSong): RemoveFromPlaylistDialog {
- val list = ArrayList()
- list.add(song)
- return create(list)
- }
-
- fun create(songs: ArrayList): RemoveFromPlaylistDialog {
- val dialog = RemoveFromPlaylistDialog()
- val args = Bundle()
- args.putParcelableArrayList(EXTRA_SONG, songs)
- dialog.arguments = args
- return dialog
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveSongFromPlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveSongFromPlaylistDialog.kt
new file mode 100644
index 000000000..b52e9fef5
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/RemoveSongFromPlaylistDialog.kt
@@ -0,0 +1,69 @@
+package code.name.monkey.retromusic.dialogs
+
+import android.app.Dialog
+import android.os.Bundle
+import androidx.core.os.bundleOf
+import androidx.core.text.HtmlCompat
+import androidx.fragment.app.DialogFragment
+import code.name.monkey.retromusic.EXTRA_SONG
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.db.SongEntity
+import code.name.monkey.retromusic.extensions.colorButtons
+import code.name.monkey.retromusic.extensions.extraNotNull
+import code.name.monkey.retromusic.extensions.materialDialog
+import code.name.monkey.retromusic.fragments.LibraryViewModel
+import code.name.monkey.retromusic.fragments.ReloadType.Playlists
+import org.koin.androidx.viewmodel.ext.android.sharedViewModel
+
+class RemoveSongFromPlaylistDialog : DialogFragment() {
+ private val libraryViewModel by sharedViewModel()
+
+ companion object {
+ fun create(song: SongEntity): RemoveSongFromPlaylistDialog {
+ val list = mutableListOf()
+ list.add(song)
+ return create(list)
+ }
+
+ fun create(songs: List): RemoveSongFromPlaylistDialog {
+ return RemoveSongFromPlaylistDialog().apply {
+ arguments = bundleOf(
+ EXTRA_SONG to songs
+ )
+ }
+ }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val songs = extraNotNull>(EXTRA_SONG).value
+ val pair = if (songs.size > 1) {
+ Pair(
+ R.string.remove_songs_from_playlist_title,
+ HtmlCompat.fromHtml(
+ String.format(getString(R.string.remove_x_songs_from_playlist), songs.size),
+ HtmlCompat.FROM_HTML_MODE_LEGACY
+ )
+ )
+ } else {
+ Pair(
+ R.string.remove_song_from_playlist_title,
+ HtmlCompat.fromHtml(
+ String.format(
+ getString(R.string.remove_song_x_from_playlist),
+ songs[0].title
+ ),
+ HtmlCompat.FROM_HTML_MODE_LEGACY
+ )
+ )
+ }
+ return materialDialog(pair.first)
+ .setMessage(pair.second)
+ .setPositiveButton(R.string.remove_action) { _, _ ->
+ libraryViewModel.deleteSongsInPlaylist(songs)
+ libraryViewModel.forceReload(Playlists)
+ }
+ .setNegativeButton(android.R.string.cancel, null)
+ .create()
+ .colorButtons()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt
index 78912d2aa..6aa6939ab 100644
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/RenamePlaylistDialog.kt
@@ -1,73 +1,57 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
package code.name.monkey.retromusic.dialogs
-import android.annotation.SuppressLint
import android.app.Dialog
import android.os.Bundle
-import android.provider.MediaStore.Audio.Playlists.Members.PLAYLIST_ID
import android.view.LayoutInflater
+import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
-import code.name.monkey.appthemehelper.util.MaterialUtil
+import code.name.monkey.retromusic.EXTRA_PLAYLIST_ID
import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.db.PlaylistEntity
+import code.name.monkey.retromusic.extensions.accentColor
import code.name.monkey.retromusic.extensions.colorButtons
import code.name.monkey.retromusic.extensions.extraNotNull
import code.name.monkey.retromusic.extensions.materialDialog
-import code.name.monkey.retromusic.util.PlaylistsUtil
+import code.name.monkey.retromusic.fragments.LibraryViewModel
+import code.name.monkey.retromusic.fragments.ReloadType
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
+import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class RenamePlaylistDialog : DialogFragment() {
+ private val libraryViewModel by sharedViewModel()
- @SuppressLint("InflateParams")
- override fun onCreateDialog(
- savedInstanceState: Bundle?
- ): Dialog {
- val layout = LayoutInflater.from(requireContext())
- .inflate(R.layout.dialog_playlist, null)
+ companion object {
+ fun create(playlistEntity: PlaylistEntity): RenamePlaylistDialog {
+ return RenamePlaylistDialog().apply {
+ arguments = bundleOf(
+ EXTRA_PLAYLIST_ID to playlistEntity
+ )
+ }
+ }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ val playlistEntity = extraNotNull(EXTRA_PLAYLIST_ID).value
+ val layout = LayoutInflater.from(requireContext()).inflate(R.layout.dialog_playlist, null)
val inputEditText: TextInputEditText = layout.findViewById(R.id.actionNewPlaylist)
- val nameContainer: TextInputLayout =
- layout.findViewById(R.id.actionNewPlaylistContainer)
- MaterialUtil.setTint(nameContainer, false)
-
+ val nameContainer: TextInputLayout = layout.findViewById(R.id.actionNewPlaylistContainer)
+ nameContainer.accentColor()
+ inputEditText.setText(playlistEntity.playlistName)
return materialDialog(R.string.rename_playlist_title)
.setView(layout)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(R.string.action_rename) { _, _ ->
val name = inputEditText.text.toString()
if (name.isNotEmpty()) {
- PlaylistsUtil.renamePlaylist(
- requireContext(),
- extraNotNull(PLAYLIST_ID).value,
- name
- )
+ libraryViewModel.renameRoomPlaylist(playlistEntity.playListId, name)
+ libraryViewModel.forceReload(ReloadType.Playlists)
+ } else {
+ nameContainer.error = "Playlist name should'nt be empty"
}
}
.create()
.colorButtons()
}
-
- companion object {
-
- fun create(playlistId: Long): RenamePlaylistDialog {
- val dialog = RenamePlaylistDialog()
- val args = Bundle()
- args.putLong(PLAYLIST_ID, playlistId)
- dialog.arguments = args
- return dialog
- }
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/RetroSingleCheckedListAdapter.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/RetroSingleCheckedListAdapter.kt
deleted file mode 100644
index c8fa03cdd..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/RetroSingleCheckedListAdapter.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package code.name.monkey.retromusic.dialogs
-
-import android.content.Context
-import android.widget.ArrayAdapter
-import code.name.monkey.retromusic.R
-
-class RetroSingleCheckedListAdapter(
- context: Context,
- resource: Int = R.layout.dialog_list_item,
- objects: MutableList
-) : ArrayAdapter(context, resource, objects) {
-
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/SavePlaylistDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/SavePlaylistDialog.kt
new file mode 100644
index 000000000..dd92a9a2d
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/SavePlaylistDialog.kt
@@ -0,0 +1,55 @@
+package code.name.monkey.retromusic.dialogs
+
+import android.app.Dialog
+import android.os.Bundle
+import android.widget.Toast
+import androidx.core.os.bundleOf
+import androidx.fragment.app.DialogFragment
+import androidx.lifecycle.lifecycleScope
+import code.name.monkey.retromusic.App
+import code.name.monkey.retromusic.EXTRA_PLAYLIST
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.db.PlaylistWithSongs
+import code.name.monkey.retromusic.extensions.colorButtons
+import code.name.monkey.retromusic.extensions.extraNotNull
+import code.name.monkey.retromusic.extensions.materialDialog
+import code.name.monkey.retromusic.util.PlaylistsUtil
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+
+class SavePlaylistDialog : DialogFragment() {
+ companion object {
+ fun create(playlistWithSongs: PlaylistWithSongs): SavePlaylistDialog {
+ return SavePlaylistDialog().apply {
+ arguments = bundleOf(
+ EXTRA_PLAYLIST to playlistWithSongs
+ )
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ lifecycleScope.launch(Dispatchers.IO) {
+ val playlistWithSongs: PlaylistWithSongs =
+ extraNotNull(EXTRA_PLAYLIST).value
+ val file = PlaylistsUtil.savePlaylistWithSongs(requireContext(), playlistWithSongs)
+ withContext(Dispatchers.Main) {
+ Toast.makeText(
+ requireContext(),
+ String.format(App.getContext().getString(R.string.saved_playlist_to), file),
+ Toast.LENGTH_LONG
+ ).show()
+ dismiss()
+ }
+ }
+ }
+
+ override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
+ return materialDialog(R.string.save_playlist_title)
+ .setView(R.layout.loading)
+ .create().colorButtons()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/SleepTimerDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/SleepTimerDialog.kt
index 466ec5320..21c43f303 100755
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/SleepTimerDialog.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/SleepTimerDialog.kt
@@ -53,8 +53,8 @@ class SleepTimerDialog : DialogFragment() {
@SuppressLint("InflateParams")
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
timerUpdater = TimerUpdater()
- val layout = LayoutInflater.from(requireContext())
- .inflate(R.layout.dialog_sleep_timer, null)
+ val layout =
+ LayoutInflater.from(requireContext()).inflate(R.layout.dialog_sleep_timer, null)
shouldFinishLastSong = layout.findViewById(R.id.shouldFinishLastSong)
seekBar = layout.findViewById(R.id.seekBar)
timerDisplay = layout.findViewById(R.id.timerDisplay)
@@ -158,7 +158,7 @@ class SleepTimerDialog : DialogFragment() {
}
}
- private inner class TimerUpdater internal constructor() :
+ private inner class TimerUpdater() :
CountDownTimer(
PreferenceUtil.nextSleepTimerElapsedRealTime - SystemClock.elapsedRealtime(),
1000
diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/SongDetailDialog.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/SongDetailDialog.kt
index d6228dc00..3409b698b 100644
--- a/app/src/main/java/code/name/monkey/retromusic/dialogs/SongDetailDialog.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/SongDetailDialog.kt
@@ -21,8 +21,6 @@ import android.os.Bundle
import android.text.Spanned
import android.util.Log
import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
import android.widget.TextView
import androidx.annotation.NonNull
import androidx.core.text.HtmlCompat
@@ -41,12 +39,6 @@ import org.jaudiotagger.tag.TagException
import java.io.File
import java.io.IOException
-inline fun ViewGroup.forEach(action: (View) -> Unit) {
- for (i in 0 until childCount) {
- action(getChildAt(i))
- }
-}
-
class SongDetailDialog : DialogFragment() {
@SuppressLint("InflateParams")
diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityEx.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityEx.kt
index 615a8acbb..843cae01e 100644
--- a/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityEx.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/extensions/ActivityEx.kt
@@ -15,13 +15,8 @@
package code.name.monkey.retromusic.extensions
import android.app.Activity
-import androidx.annotation.IdRes
import androidx.appcompat.app.AppCompatActivity
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentActivity
-import androidx.fragment.app.FragmentTransaction
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
-import code.name.monkey.retromusic.R
import com.google.android.material.appbar.MaterialToolbar
fun AppCompatActivity.applyToolbar(toolbar: MaterialToolbar) {
@@ -30,41 +25,6 @@ fun AppCompatActivity.applyToolbar(toolbar: MaterialToolbar) {
setSupportActionBar(toolbar)
}
-fun FragmentActivity?.addFragment(
- @IdRes idRes: Int = R.id.container,
- fragment: Fragment,
- tag: String? = null,
- addToBackStack: Boolean = false
-) {
- val compatActivity = this as? AppCompatActivity ?: return
- compatActivity.supportFragmentManager.beginTransaction()
- .apply {
- add(fragment, tag)
- setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
- if (addToBackStack) {
- addToBackStack(null)
- }
- commitNow()
- }
-}
-
-fun AppCompatActivity.replaceFragment(
- @IdRes id: Int = R.id.container,
- fragment: Fragment,
- tag: String? = null,
- addToBackStack: Boolean = false
-) {
- val compatActivity = this ?: return
- compatActivity.supportFragmentManager.beginTransaction()
- .apply {
- replace(id, fragment, tag)
- if (addToBackStack) {
- addToBackStack(null)
- }
- commit()
- }
-}
-
inline fun Activity.extra(key: String, default: T? = null) = lazy {
val value = intent?.extras?.get(key)
if (value is T) value else default
diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/ColorExt.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/ColorExt.kt
index cee067c23..9afbd431e 100644
--- a/app/src/main/java/code/name/monkey/retromusic/extensions/ColorExt.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/extensions/ColorExt.kt
@@ -18,12 +18,18 @@ import android.app.Dialog
import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Color
+import android.graphics.drawable.Drawable
import android.widget.Button
import android.widget.CheckBox
import android.widget.SeekBar
import androidx.annotation.AttrRes
+import androidx.annotation.CheckResult
import androidx.annotation.ColorInt
+import androidx.annotation.ColorRes
+import androidx.appcompat.widget.AppCompatImageView
import androidx.appcompat.widget.Toolbar
+import androidx.core.content.ContextCompat
+import androidx.core.graphics.drawable.DrawableCompat
import androidx.fragment.app.Fragment
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.ATHUtil
@@ -33,6 +39,8 @@ import code.name.monkey.retromusic.App
import code.name.monkey.retromusic.R
import com.google.android.material.button.MaterialButton
import com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+import com.google.android.material.floatingactionbutton.FloatingActionButton
+import com.google.android.material.progressindicator.ProgressIndicator
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
@@ -91,6 +99,10 @@ fun Button.accentTextColor() {
setTextColor(ThemeStore.accentColor(App.getContext()))
}
+fun MaterialButton.accentTextColor() {
+ setTextColor(ThemeStore.accentColor(App.getContext()))
+}
+
fun SeekBar.applyColor(@ColorInt color: Int) {
thumbTintList = ColorStateList.valueOf(color)
progressTintList = ColorStateList.valueOf(color)
@@ -107,6 +119,15 @@ fun ExtendedFloatingActionButton.accentColor() {
iconTint = textColorStateList
}
+fun FloatingActionButton.accentColor() {
+ val color = ThemeStore.accentColor(context)
+ val textColor = MaterialValueHelper.getPrimaryTextColor(context, ColorUtil.isColorLight(color))
+ val colorStateList = ColorStateList.valueOf(color)
+ val textColorStateList = ColorStateList.valueOf(textColor)
+ backgroundTintList = colorStateList
+ imageTintList = textColorStateList
+}
+
fun MaterialButton.applyColor(color: Int) {
val backgroundColorStateList = ColorStateList.valueOf(color)
val textColorColorStateList = ColorStateList.valueOf(
@@ -120,6 +141,12 @@ fun MaterialButton.applyColor(color: Int) {
iconTint = textColorColorStateList
}
+fun MaterialButton.applyOutlineColor(color: Int) {
+ val textColorColorStateList = ColorStateList.valueOf(color)
+ setTextColor(textColorColorStateList)
+ iconTint = textColorColorStateList
+}
+
fun TextInputLayout.accentColor() {
val accentColor = ThemeStore.accentColor(context)
val colorState = ColorStateList.valueOf(accentColor)
@@ -128,6 +155,39 @@ fun TextInputLayout.accentColor() {
isHintAnimationEnabled = true
}
+fun ProgressIndicator.accentColor() {
+ val accentColor = ThemeStore.accentColor(context)
+ indicatorColors = intArrayOf(accentColor)
+ trackColor = ColorUtil.withAlpha(accentColor, 0.2f)
+}
+
+fun ProgressIndicator.applyColor(color: Int) {
+ indicatorColors = intArrayOf(color)
+ trackColor = ColorUtil.withAlpha(color, 0.2f)
+}
+
fun TextInputEditText.accentColor() {
-}
\ No newline at end of file
+}
+
+fun AppCompatImageView.accentColor(): Int {
+ return ThemeStore.accentColor(context)
+}
+
+@CheckResult
+fun Drawable.tint(@ColorInt color: Int): Drawable {
+ val tintedDrawable = DrawableCompat.wrap(this).mutate()
+ DrawableCompat.setTint(this, color)
+ return tintedDrawable
+}
+
+@CheckResult
+fun Drawable.tint(context: Context, @ColorRes color: Int): Drawable {
+ return tint(context.getColorCompat(color))
+}
+
+@ColorInt
+fun Context.getColorCompat(@ColorRes colorRes: Int): Int {
+ return ContextCompat.getColor(this, colorRes)
+}
+
diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/DialogExtension.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/DialogExtension.kt
index d2c383101..c56a40459 100644
--- a/app/src/main/java/code/name/monkey/retromusic/extensions/DialogExtension.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/extensions/DialogExtension.kt
@@ -8,7 +8,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
fun DialogFragment.materialDialog(title: Int): MaterialAlertDialogBuilder {
return MaterialAlertDialogBuilder(
requireContext(),
- R.style.ThemeOverlay_MaterialComponents_Dialog_Alert
+ R.style.MaterialAlertDialogTheme
).setTitle(title)
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentExt.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentExt.kt
index 8f53f469a..a826d1535 100644
--- a/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentExt.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/extensions/FragmentExt.kt
@@ -2,12 +2,15 @@ package code.name.monkey.retromusic.extensions
import android.content.Context
import android.content.res.Configuration
+import android.graphics.drawable.Drawable
import android.os.PowerManager
import android.widget.Toast
+import androidx.annotation.DrawableRes
import androidx.annotation.IdRes
import androidx.annotation.IntegerRes
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
+import androidx.appcompat.content.res.AppCompatResources
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.navigation.fragment.NavHostFragment
@@ -51,7 +54,8 @@ val FragmentManager.currentNavigationFragment: Fragment?
get() = primaryNavigationFragment?.childFragmentManager?.fragments?.first()
fun AppCompatActivity.currentFragment(navHostId: Int): Fragment? {
- val navHostFragment: NavHostFragment = supportFragmentManager.findFragmentById(navHostId) as NavHostFragment
+ val navHostFragment: NavHostFragment =
+ supportFragmentManager.findFragmentById(navHostId) as NavHostFragment
navHostFragment.targetFragment
return navHostFragment.childFragmentManager.fragments.first()
}
@@ -72,4 +76,12 @@ fun Fragment.showToast(@StringRes stringRes: Int) {
fun Fragment.showToast(message: String) {
Toast.makeText(requireContext(), message, Toast.LENGTH_SHORT).show()
+}
+
+fun Context.getDrawableCompat(@DrawableRes drawableRes: Int): Drawable {
+ return AppCompatResources.getDrawable(this, drawableRes)!!
+}
+
+fun Fragment.getDrawableCompat(@DrawableRes drawableRes: Int): Drawable {
+ return AppCompatResources.getDrawable(requireContext(), drawableRes)!!
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt b/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt
index da321935e..0f9e30e8a 100644
--- a/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/extensions/ViewExtensions.kt
@@ -14,13 +14,10 @@
package code.name.monkey.retromusic.extensions
-import android.content.res.ColorStateList
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
-import android.widget.SeekBar
-import androidx.annotation.ColorInt
import androidx.annotation.LayoutRes
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.TintHelper
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/CoroutineViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/CoroutineViewModel.kt
new file mode 100644
index 000000000..9b6a5ca4c
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/CoroutineViewModel.kt
@@ -0,0 +1,23 @@
+package code.name.monkey.retromusic.fragments
+
+import androidx.lifecycle.ViewModel
+import kotlinx.coroutines.*
+import kotlin.coroutines.CoroutineContext
+
+open class CoroutineViewModel(
+ private val mainDispatcher: CoroutineDispatcher
+) : ViewModel() {
+ private val job = Job()
+ protected val scope = CoroutineScope(job + mainDispatcher)
+
+ protected fun launch(
+ context: CoroutineContext = mainDispatcher,
+ start: CoroutineStart = CoroutineStart.DEFAULT,
+ block: suspend CoroutineScope.() -> Unit
+ ) = scope.launch(context, start, block)
+
+ override fun onCleared() {
+ super.onCleared()
+ job.cancel()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/DetailListFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/DetailListFragment.kt
index 53273281f..6c7230a52 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/DetailListFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/DetailListFragment.kt
@@ -3,6 +3,8 @@ package code.name.monkey.retromusic.fragments
import android.os.Bundle
import android.view.View
import android.widget.ImageView
+import androidx.lifecycle.Observer
+import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
@@ -10,15 +12,14 @@ import code.name.monkey.retromusic.*
import code.name.monkey.retromusic.adapter.album.AlbumAdapter
import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
import code.name.monkey.retromusic.adapter.song.SongAdapter
+import code.name.monkey.retromusic.db.toSong
import code.name.monkey.retromusic.fragments.albums.AlbumClickListener
import code.name.monkey.retromusic.fragments.artists.ArtistClickListener
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist
-import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.RealRepository
import kotlinx.android.synthetic.main.fragment_playlist_detail.*
-import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
@@ -34,6 +35,7 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
super.onActivityCreated(savedInstanceState)
mainActivity.setSupportActionBar(toolbar)
mainActivity.hideBottomBarVisibility(false)
+ progressIndicator.hide()
when (args.type) {
TOP_ARTISTS -> {
loadArtists(R.string.top_artists, TOP_ARTISTS)
@@ -47,32 +49,88 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
RECENT_ALBUMS -> {
loadAlbums(R.string.recent_albums, RECENT_ALBUMS)
}
- FAVOURITES -> {
- loadFavorite()
- }
+ FAVOURITES -> loadFavorite()
+ HISTORY_PLAYLIST -> loadHistory()
+ LAST_ADDED_PLAYLIST -> lastAddedSongs()
+ TOP_PLAYED_PLAYLIST -> topPlayed()
}
}
+ private fun lastAddedSongs() {
+ toolbar.setTitle(R.string.last_added)
+ val songAdapter = SongAdapter(
+ requireActivity(),
+ mutableListOf(),
+ R.layout.item_list, null
+ )
+ recyclerView.apply {
+ adapter = songAdapter
+ layoutManager = linearLayoutManager()
+ }
+ lifecycleScope.launch(IO) {
+ val songs = repository.recentSongs()
+ withContext(Main) { songAdapter.swapDataSet(songs) }
+ }
+ }
+
+ private fun topPlayed() {
+ toolbar.setTitle(R.string.my_top_tracks)
+ val songAdapter = SongAdapter(
+ requireActivity(),
+ mutableListOf(),
+ R.layout.item_list, null
+ )
+ recyclerView.apply {
+ adapter = songAdapter
+ layoutManager = linearLayoutManager()
+ }
+ lifecycleScope.launch(IO) {
+ val songs = repository.playCountSongs().map {
+ it.toSong()
+ }
+ withContext(Main) { songAdapter.swapDataSet(songs) }
+ }
+ }
+
+ private fun loadHistory() {
+ toolbar.setTitle(R.string.history)
+
+ val songAdapter = SongAdapter(
+ requireActivity(),
+ mutableListOf(),
+ R.layout.item_list, null
+ )
+ recyclerView.apply {
+ adapter = songAdapter
+ layoutManager = linearLayoutManager()
+ }
+ repository.observableHistorySongs().observe(viewLifecycleOwner, Observer {
+ val songs = it.map { historyEntity -> historyEntity.toSong() }
+ songAdapter.swapDataSet(songs)
+ })
+ }
+
private fun loadFavorite() {
toolbar.setTitle(R.string.favorites)
- CoroutineScope(IO).launch {
- val songs = repository.favoritePlaylistHome()
- withContext(Main) {
- recyclerView.apply {
- adapter = SongAdapter(
- requireActivity(),
- songs.arrayList as MutableList,
- R.layout.item_list, null
- )
- layoutManager = linearLayoutManager()
- }
- }
+ val songAdapter = SongAdapter(
+ requireActivity(),
+ mutableListOf(),
+ R.layout.item_list, null
+ )
+ recyclerView.apply {
+ adapter = songAdapter
+ layoutManager = linearLayoutManager()
}
+ repository.favorites().observe(viewLifecycleOwner, Observer {
+ println(it.size)
+ val songs = it.map { songEntity -> songEntity.toSong() }
+ songAdapter.swapDataSet(songs)
+ })
}
private fun loadArtists(title: Int, type: Int) {
toolbar.setTitle(title)
- CoroutineScope(IO).launch {
+ lifecycleScope.launch(IO) {
val artists =
if (type == TOP_ARTISTS) repository.topArtists() else repository.recentArtists()
withContext(Main) {
@@ -86,7 +144,7 @@ class DetailListFragment : AbsMainActivityFragment(R.layout.fragment_playlist_de
private fun loadAlbums(title: Int, type: Int) {
toolbar.setTitle(title)
- CoroutineScope(IO).launch {
+ lifecycleScope.launch(IO) {
val albums =
if (type == TOP_ALBUMS) repository.topAlbums() else repository.recentAlbums()
withContext(Main) {
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt
index dd4727a70..a60b92569 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt
@@ -4,83 +4,129 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import code.name.monkey.retromusic.db.PlaylistEntity
+import code.name.monkey.retromusic.db.PlaylistWithSongs
+import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.fragments.ReloadType.*
+import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener
import code.name.monkey.retromusic.model.*
import code.name.monkey.retromusic.repository.RealRepository
-import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers.IO
-import kotlinx.coroutines.async
import kotlinx.coroutines.launch
class LibraryViewModel(
- private val realRepository: RealRepository
+ private val repository: RealRepository
) : ViewModel(), MusicServiceEventListener {
private val paletteColor = MutableLiveData()
private val albums = MutableLiveData>()
private val songs = MutableLiveData>()
private val artists = MutableLiveData>()
- private val playlists = MutableLiveData>()
+ private val playlists = MutableLiveData>()
+ private val legacyPlaylists = MutableLiveData>()
private val genres = MutableLiveData>()
private val home = MutableLiveData>()
val paletteColorLiveData: LiveData = paletteColor
- val homeLiveData: LiveData> = home
- val albumsLiveData: LiveData> = albums
- val songsLiveData: LiveData> = songs
- val artistsLiveData: LiveData> = artists
- val playlisitsLiveData: LiveData> = playlists
- val genresLiveData: LiveData> = genres
init {
- viewModelScope.launch {
- loadLibraryContent()
+ fetchHomeSections()
+ }
+
+ private fun loadLibraryContent() = viewModelScope.launch(IO) {
+ fetchHomeSections()
+ fetchSongs()
+ fetchAlbums()
+ fetchArtists()
+ fetchGenres()
+ fetchPlaylists()
+ }
+
+ fun getSongs(): LiveData> {
+ fetchSongs()
+ return songs
+ }
+
+ fun getAlbums(): LiveData> {
+ fetchAlbums()
+ return albums
+ }
+
+ fun getArtists(): LiveData> {
+ fetchArtists()
+ return artists
+ }
+
+ fun getPlaylists(): LiveData> {
+ fetchPlaylists()
+ return playlists
+ }
+
+ fun getLegacyPlaylist(): LiveData> {
+ fetchLegacyPlaylist()
+ return legacyPlaylists
+ }
+
+ fun getGenre(): LiveData> {
+ fetchGenres()
+ return genres
+ }
+
+ fun getHome(): LiveData> {
+ return home
+ }
+
+ private fun fetchSongs() {
+ viewModelScope.launch(IO) {
+ songs.postValue(repository.allSongs())
}
}
- private fun loadLibraryContent() = viewModelScope.launch {
- songs.value = loadSongs.await()
- albums.value = loadAlbums.await()
- artists.value = loadArtists.await()
- playlists.value = loadPlaylists.await()
- genres.value = loadGenres.await()
- home.value = loadHome.await()
+ private fun fetchAlbums() {
+ viewModelScope.launch(IO) {
+ albums.postValue(repository.fetchAlbums())
+ }
}
- private val loadHome: Deferred>
- get() = viewModelScope.async { realRepository.homeSections() }
-
- private val loadSongs: Deferred>
- get() = viewModelScope.async(IO) { realRepository.allSongs() }
-
- private val loadAlbums: Deferred>
- get() = viewModelScope.async(IO) {
- realRepository.allAlbums()
+ private fun fetchArtists() {
+ viewModelScope.launch(IO) {
+ artists.postValue(repository.fetchArtists())
}
+ }
- private val loadArtists: Deferred>
- get() = viewModelScope.async(IO) {
- realRepository.albumArtists()
+ private fun fetchPlaylists() {
+ viewModelScope.launch(IO) {
+ playlists.postValue(repository.fetchPlaylistWithSongs())
}
+ }
- private val loadPlaylists: Deferred>
- get() = viewModelScope.async(IO) {
- realRepository.allPlaylists()
+ private fun fetchLegacyPlaylist() {
+ viewModelScope.launch(IO) {
+ legacyPlaylists.postValue(repository.fetchLegacyPlaylist())
}
+ }
- private val loadGenres: Deferred>
- get() = viewModelScope.async(IO) {
- realRepository.allGenres()
+ private fun fetchGenres() {
+ viewModelScope.launch(IO) {
+ genres.postValue(repository.fetchGenres())
}
+ }
+ private fun fetchHomeSections() {
+ viewModelScope.launch(IO) {
+ home.postValue(repository.homeSections())
+ }
+ }
fun forceReload(reloadType: ReloadType) = viewModelScope.launch {
when (reloadType) {
- Songs -> songs.value = loadSongs.await()
- Albums -> albums.value = loadAlbums.await()
- Artists -> artists.value = loadArtists.await()
- HomeSections -> songs.value = loadSongs.await()
+ Songs -> fetchSongs()
+ Albums -> fetchAlbums()
+ Artists -> fetchArtists()
+ HomeSections -> fetchHomeSections()
+ Playlists -> fetchPlaylists()
+ Genres -> fetchGenres()
}
}
@@ -89,11 +135,10 @@ class LibraryViewModel(
}
override fun onMediaStoreChanged() {
- loadLibraryContent()
println("onMediaStoreChanged")
+ loadLibraryContent()
}
-
override fun onServiceConnected() {
println("onServiceConnected")
}
@@ -108,6 +153,7 @@ class LibraryViewModel(
override fun onPlayingMetaChanged() {
println("onPlayingMetaChanged")
+
}
override fun onPlayStateChanged() {
@@ -122,11 +168,76 @@ class LibraryViewModel(
println("onShuffleModeChanged")
}
+ fun shuffleSongs() = viewModelScope.launch(IO) {
+ val songs = repository.allSongs()
+ MusicPlayerRemote.openAndShuffleQueue(
+ songs,
+ true
+ )
+ }
+
+ fun renameRoomPlaylist(playListId: Int, name: String) = viewModelScope.launch(IO) {
+ repository.renameRoomPlaylist(playListId, name)
+ }
+
+ fun deleteSongsInPlaylist(songs: List) = viewModelScope.launch(IO) {
+ repository.deleteSongsInPlaylist(songs)
+ }
+
+ fun deleteSongsFromPlaylist(playlists: List) = viewModelScope.launch(IO) {
+ repository.deletePlaylistSongs(playlists)
+ }
+
+ fun deleteRoomPlaylist(playlists: List) = viewModelScope.launch(IO) {
+ repository.deleteRoomPlaylist(playlists)
+ }
+
+ suspend fun albumById(id: Int) = repository.albumById(id)
+ suspend fun artistById(id: Int) = repository.artistById(id)
+ suspend fun favoritePlaylist() = repository.favoritePlaylist()
+ suspend fun isFavoriteSong(song: SongEntity) = repository.isFavoriteSong(song)
+ suspend fun insertSongs(songs: List) = repository.insertSongs(songs)
+ suspend fun removeSongFromPlaylist(songEntity: SongEntity) =
+ repository.removeSongFromPlaylist(songEntity)
+
+ suspend fun checkPlaylistExists(playlistName: String): List =
+ repository.checkPlaylistExists(playlistName)
+
+ suspend fun createPlaylist(playlistEntity: PlaylistEntity): Long =
+ repository.createPlaylist(playlistEntity)
+
+ fun importPlaylists() = viewModelScope.launch(IO) {
+ val playlists = repository.fetchLegacyPlaylist()
+ playlists.forEach { playlist ->
+ val playlistEntity = repository.checkPlaylistExists(playlist.name).firstOrNull()
+ if (playlistEntity != null) {
+ val songEntities = playlist.getSongs().map {
+ it.toSongEntity(playlistEntity.playListId)
+ }
+ repository.insertSongs(songEntities)
+ } else {
+ val playListId = createPlaylist(PlaylistEntity(playlist.name))
+ val songEntities = playlist.getSongs().map {
+ it.toSongEntity(playListId.toInt())
+ }
+ repository.insertSongs(songEntities)
+ }
+ forceReload(Playlists)
+ }
+ }
+
+ fun deleteTracks(songs: List) = viewModelScope.launch(IO) {
+ repository.deleteSongs(songs)
+ fetchPlaylists()
+ loadLibraryContent()
+ }
}
enum class ReloadType {
Songs,
Albums,
Artists,
- HomeSections
+ HomeSections,
+ Playlists,
+ Genres,
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/MiniPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/MiniPlayerFragment.kt
index 9f05dc434..9a16d6566 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/MiniPlayerFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/MiniPlayerFragment.kt
@@ -11,18 +11,14 @@ import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.view.animation.DecelerateInterpolator
-import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.retromusic.R
-import code.name.monkey.retromusic.extensions.show
-import code.name.monkey.retromusic.extensions.textColorPrimary
-import code.name.monkey.retromusic.extensions.textColorSecondary
+import code.name.monkey.retromusic.extensions.*
import code.name.monkey.retromusic.fragments.base.AbsMusicServiceFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.MusicProgressViewUpdateHelper
import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
-import code.name.monkey.retromusic.util.ViewUtil
import kotlinx.android.synthetic.main.fragment_mini_player.*
import kotlin.math.abs
@@ -67,7 +63,7 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
private fun setUpMiniPlayer() {
setUpPlayPauseButton()
- ViewUtil.setProgressDrawable(progressBar, ThemeStore.accentColor(requireContext()))
+ progressBar.accentColor()
}
private fun setUpPlayPauseButton() {
@@ -129,6 +125,10 @@ open class MiniPlayerFragment : AbsMusicServiceFragment(R.layout.fragment_mini_p
}
}
+ fun updateProgressBar(paletteColor: Int) {
+ progressBar.applyColor(paletteColor)
+ }
+
class FlingPlayBackController(context: Context) : View.OnTouchListener {
private var flingPlayBackController: GestureDetector
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt
index dacaff2d8..19e085222 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/NowPlayingScreen.kt
@@ -24,7 +24,6 @@ enum class NowPlayingScreen constructor(
Gradient(R.string.gradient, R.drawable.np_gradient, 17),
Material(R.string.material, R.drawable.np_material, 11),
Normal(R.string.normal, R.drawable.np_normal, 0),
-
//Peak(R.string.peak, R.drawable.np_peak, 14),
Plain(R.string.plain, R.drawable.np_plain, 3),
Simple(R.string.simple, R.drawable.np_simple, 8),
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt
index 9bc60bd52..bade59ff5 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsFragment.kt
@@ -6,7 +6,9 @@ import android.os.Bundle
import android.view.*
import androidx.appcompat.app.AppCompatActivity
import androidx.core.os.bundleOf
+import androidx.core.text.HtmlCompat
import androidx.lifecycle.Observer
+import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
@@ -25,16 +27,20 @@ import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.dialogs.DeleteSongsDialog
import code.name.monkey.retromusic.extensions.applyColor
+import code.name.monkey.retromusic.extensions.applyOutlineColor
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.AlbumGlideRequest
import code.name.monkey.retromusic.glide.ArtistGlideRequest
import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
+import code.name.monkey.retromusic.glide.SingleColorTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.helper.SortOrder
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist
+import code.name.monkey.retromusic.network.Result
import code.name.monkey.retromusic.network.model.LastFmAlbum
+import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
@@ -42,6 +48,10 @@ import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_album_content.*
import kotlinx.android.synthetic.main.fragment_album_details.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import java.util.*
@@ -66,23 +76,13 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
mainActivity.hideBottomBarVisibility(false)
mainActivity.addMusicServiceEventListener(detailsViewModel)
mainActivity.setSupportActionBar(toolbar)
-
- toolbar.title = null
-
+ toolbar.title = " "
postponeEnterTransition()
detailsViewModel.getAlbum().observe(viewLifecycleOwner, Observer {
- showAlbum(it)
startPostponedEnterTransition()
+ showAlbum(it)
})
- detailsViewModel.getArtist().observe(viewLifecycleOwner, Observer {
- loadArtistImage(it)
- })
- detailsViewModel.getMoreAlbums().observe(viewLifecycleOwner, Observer {
- moreAlbums(it)
- })
- detailsViewModel.getAlbumInfo().observe(viewLifecycleOwner, Observer {
- aboutAlbum(it)
- })
+
setupRecyclerView()
artistImage.setOnClickListener {
requireActivity().findNavController(R.id.fragment_container)
@@ -140,14 +140,12 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
this.album = album
albumTitle.text = album.title
- val songText =
- resources.getQuantityString(
- R.plurals.albumSongs,
- album.songCount,
- album.songCount
- )
+ val songText = resources.getQuantityString(
+ R.plurals.albumSongs,
+ album.songCount,
+ album.songCount
+ )
songTitle.text = songText
-
if (MusicUtil.getYearString(album.year) == "-") {
albumText.text = String.format(
"%s • %s",
@@ -162,10 +160,25 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
MusicUtil.getReadableDurationString(MusicUtil.getTotalDuration(album.songs))
)
}
- loadAlbumCover()
+ loadAlbumCover(album)
simpleSongAdapter.swapDataSet(album.songs)
- detailsViewModel.loadArtist(album.artistId)
- detailsViewModel.loadAlbumInfo(album)
+ detailsViewModel.getArtist(album.artistId).observe(viewLifecycleOwner, Observer {
+ loadArtistImage(it)
+ })
+
+ detailsViewModel.getAlbumInfo(album).observe(viewLifecycleOwner, Observer { result ->
+ when (result) {
+ is Result.Loading -> {
+ println("Loading")
+ }
+ is Result.Error -> {
+ println("Error")
+ }
+ is Result.Success -> {
+ aboutAlbum(result.data)
+ }
+ }
+ })
}
private fun moreAlbums(albums: List) {
@@ -191,7 +204,10 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
aboutAlbumTitle.show()
aboutAlbumTitle.text =
String.format(getString(R.string.about_album_label), lastFmAlbum.album.name)
- aboutAlbumText.text = lastFmAlbum.album.wiki.content
+ aboutAlbumText.text = HtmlCompat.fromHtml(
+ lastFmAlbum.album.wiki.content,
+ HtmlCompat.FROM_HTML_MODE_LEGACY
+ )
}
if (lastFmAlbum.album.listeners.isNotEmpty()) {
listeners.show()
@@ -206,7 +222,11 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
}
private fun loadArtistImage(artist: Artist) {
+ detailsViewModel.getMoreAlbums(artist).observe(viewLifecycleOwner, Observer {
+ moreAlbums(it)
+ })
ArtistGlideRequest.Builder.from(Glide.with(requireContext()), artist)
+ .forceDownload(PreferenceUtil.isAllowedToDownloadMetadata())
.generatePalette(requireContext())
.build()
.dontAnimate()
@@ -217,24 +237,21 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
})
}
- private fun loadAlbumCover() {
+ private fun loadAlbumCover(album: Album) {
AlbumGlideRequest.Builder.from(Glide.with(requireContext()), album.safeGetFirstSong())
- .checkIgnoreMediaStore(requireContext())
- .ignoreMediaStore(PreferenceUtil.isIgnoreMediaStoreArtwork)
+ .checkIgnoreMediaStore()
.generatePalette(requireContext())
.build()
- .dontAnimate()
- .dontTransform()
- .into(object : RetroMusicColoredTarget(image) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- setColors(colors)
+ .into(object : SingleColorTarget(image) {
+ override fun onColorReady(color: Int) {
+ setColors(color)
}
})
}
- private fun setColors(color: MediaNotificationProcessor) {
- shuffleAction.applyColor(color.backgroundColor)
- playAction.applyColor(color.backgroundColor)
+ private fun setColors(color: Int) {
+ shuffleAction.applyColor(color)
+ playAction.applyOutlineColor(color)
}
override fun onAlbumClick(albumId: Int, view: View) {
@@ -275,7 +292,13 @@ class AlbumDetailsFragment : AbsMainActivityFragment(R.layout.fragment_album_det
return true
}
R.id.action_add_to_playlist -> {
- AddToPlaylistDialog.create(songs).show(childFragmentManager, "ADD_PLAYLIST")
+ lifecycleScope.launch(Dispatchers.IO) {
+ val playlists = get().fetchPlaylists()
+ withContext(Dispatchers.Main) {
+ AddToPlaylistDialog.create(playlists, songs)
+ .show(childFragmentManager, "ADD_PLAYLIST")
+ }
+ }
return true
}
R.id.action_delete_from_device -> {
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsViewModel.kt
index 93b637e71..3311046e4 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsViewModel.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumDetailsViewModel.kt
@@ -1,64 +1,44 @@
package code.name.monkey.retromusic.fragments.albums
import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.liveData
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener
import code.name.monkey.retromusic.model.Album
import code.name.monkey.retromusic.model.Artist
+import code.name.monkey.retromusic.network.Result
import code.name.monkey.retromusic.network.model.LastFmAlbum
import code.name.monkey.retromusic.repository.RealRepository
-import kotlinx.coroutines.Deferred
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.async
-import kotlinx.coroutines.launch
+import kotlinx.coroutines.Dispatchers.IO
class AlbumDetailsViewModel(
private val realRepository: RealRepository,
private val albumId: Int
) : ViewModel(), MusicServiceEventListener {
- private val _album = MutableLiveData()
- private val _artist = MutableLiveData()
- private val _lastFmAlbum = MutableLiveData()
- private val _moreAlbums = MutableLiveData>()
-
- fun getAlbum(): LiveData = _album
- fun getArtist(): LiveData = _artist
- fun getAlbumInfo(): LiveData = _lastFmAlbum
- fun getMoreAlbums(): LiveData> = _moreAlbums;
-
- init {
- loadAlbumDetails()
+ fun getAlbum(): LiveData = liveData(IO) {
+ val album = realRepository.albumByIdAsync(albumId)
+ emit(album)
}
- private fun loadAlbumDetails() = viewModelScope.launch {
- val album = loadAlbumAsync.await() ?: throw NullPointerException("Album couldn't found")
- _album.postValue(album)
- }
-
- fun loadAlbumInfo(album: Album) = viewModelScope.launch(Dispatchers.IO) {
- val lastFmAlbum = realRepository.albumInfo(album.artistName ?: "-", album.title ?: "-")
- _lastFmAlbum.postValue(lastFmAlbum)
- }
-
- fun loadArtist(artistId: Int) = viewModelScope.launch(Dispatchers.IO) {
+ fun getArtist(artistId: Int): LiveData = liveData(IO) {
val artist = realRepository.artistById(artistId)
- _artist.postValue(artist)
-
- artist.albums?.filter { item -> item.id != albumId }?.let { albums ->
- if (albums.isNotEmpty()) _moreAlbums.postValue(albums)
- }
+ emit(artist)
}
- private val loadAlbumAsync: Deferred
- get() = viewModelScope.async(Dispatchers.IO) {
- realRepository.albumById(albumId)
+ fun getAlbumInfo(album: Album): LiveData> = liveData {
+ emit(Result.Loading)
+ emit( realRepository.albumInfo(album.artistName ?: "-", album.title ?: "-"))
+ }
+
+ fun getMoreAlbums(artist: Artist): LiveData> = liveData(IO) {
+ artist.albums?.filter { item -> item.id != albumId }?.let { albums ->
+ if (albums.isNotEmpty()) emit(albums)
}
+ }
override fun onMediaStoreChanged() {
- loadAlbumDetails()
+
}
override fun onServiceConnected() {}
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt
index 47c060da4..9f7b7ce0f 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/albums/AlbumsFragment.kt
@@ -1,26 +1,29 @@
package code.name.monkey.retromusic.fragments.albums
import android.os.Bundle
-import android.view.View
+import android.view.*
import androidx.core.os.bundleOf
import androidx.lifecycle.Observer
-import androidx.navigation.findNavController
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.recyclerview.widget.GridLayoutManager
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.album.AlbumAdapter
+import code.name.monkey.retromusic.extensions.findActivityNavController
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
+import code.name.monkey.retromusic.helper.SortOrder
+import code.name.monkey.retromusic.helper.SortOrder.AlbumSortOrder
import code.name.monkey.retromusic.util.PreferenceUtil
+import code.name.monkey.retromusic.util.RetroUtil
-class AlbumsFragment :
- AbsRecyclerViewCustomGridSizeFragment(),
+
+class AlbumsFragment : AbsRecyclerViewCustomGridSizeFragment(),
AlbumClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- libraryViewModel.albumsLiveData.observe(viewLifecycleOwner, Observer {
+ libraryViewModel.getAlbums().observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
else
@@ -95,8 +98,7 @@ class AlbumsFragment :
}
override fun onAlbumClick(albumId: Int, view: View) {
- val controller = requireActivity().findNavController(R.id.fragment_container)
- controller.navigate(
+ findActivityNavController(R.id.fragment_container).navigate(
R.id.albumDetailsFragment,
bundleOf(EXTRA_ALBUM_ID to albumId),
null,
@@ -105,6 +107,181 @@ class AlbumsFragment :
)
)
}
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ val gridSizeItem: MenuItem = menu.findItem(R.id.action_grid_size)
+ if (RetroUtil.isLandscape()) {
+ gridSizeItem.setTitle(R.string.action_grid_size_land)
+ }
+ setUpGridSizeMenu(gridSizeItem.subMenu)
+ val layoutItem = menu.findItem(R.id.action_layout_type)
+ setupLayoutMenu(layoutItem.subMenu)
+ setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
+ super.onCreateOptionsMenu(menu, inflater)
+ }
+
+ private fun setUpSortOrderMenu(
+ sortOrderMenu: SubMenu
+ ) {
+ val currentSortOrder: String? = getSortOrder()
+ sortOrderMenu.clear()
+ sortOrderMenu.add(
+ 0,
+ R.id.action_album_sort_order_asc,
+ 0,
+ R.string.sort_order_a_z
+ ).isChecked =
+ currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_A_Z)
+ sortOrderMenu.add(
+ 0,
+ R.id.action_album_sort_order_desc,
+ 1,
+ R.string.sort_order_z_a
+ ).isChecked =
+ currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_Z_A)
+ sortOrderMenu.add(
+ 0,
+ R.id.action_album_sort_order_artist,
+ 2,
+ R.string.sort_order_artist
+ ).isChecked =
+ currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_ARTIST)
+ sortOrderMenu.add(
+ 0,
+ R.id.action_album_sort_order_year,
+ 3,
+ R.string.sort_order_year
+ ).isChecked =
+ currentSortOrder.equals(SortOrder.AlbumSortOrder.ALBUM_YEAR)
+
+ sortOrderMenu.setGroupCheckable(0, true, true)
+ }
+
+ private fun setupLayoutMenu(
+ subMenu: SubMenu
+ ) {
+ when (itemLayoutRes()) {
+ R.layout.item_card -> subMenu.findItem(R.id.action_layout_card).isChecked = true
+ R.layout.item_grid -> subMenu.findItem(R.id.action_layout_normal).isChecked = true
+ R.layout.item_card_color ->
+ subMenu.findItem(R.id.action_layout_colored_card).isChecked = true
+ R.layout.item_grid_circle ->
+ subMenu.findItem(R.id.action_layout_circular).isChecked = true
+ R.layout.image -> subMenu.findItem(R.id.action_layout_image).isChecked = true
+ R.layout.item_image_gradient ->
+ subMenu.findItem(R.id.action_layout_gradient_image).isChecked = true
+ }
+ }
+
+ private fun setUpGridSizeMenu(
+ gridSizeMenu: SubMenu
+ ) {
+ when (getGridSize()) {
+ 1 -> gridSizeMenu.findItem(R.id.action_grid_size_1).isChecked =
+ true
+ 2 -> gridSizeMenu.findItem(R.id.action_grid_size_2).isChecked = true
+ 3 -> gridSizeMenu.findItem(R.id.action_grid_size_3).isChecked = true
+ 4 -> gridSizeMenu.findItem(R.id.action_grid_size_4).isChecked = true
+ 5 -> gridSizeMenu.findItem(R.id.action_grid_size_5).isChecked = true
+ 6 -> gridSizeMenu.findItem(R.id.action_grid_size_6).isChecked = true
+ 7 -> gridSizeMenu.findItem(R.id.action_grid_size_7).isChecked = true
+ 8 -> gridSizeMenu.findItem(R.id.action_grid_size_8).isChecked = true
+ }
+ val gridSize: Int = maxGridSize
+ if (gridSize < 8) {
+ gridSizeMenu.findItem(R.id.action_grid_size_8).isVisible = false
+ }
+ if (gridSize < 7) {
+ gridSizeMenu.findItem(R.id.action_grid_size_7).isVisible = false
+ }
+ if (gridSize < 6) {
+ gridSizeMenu.findItem(R.id.action_grid_size_6).isVisible = false
+ }
+ if (gridSize < 5) {
+ gridSizeMenu.findItem(R.id.action_grid_size_5).isVisible = false
+ }
+ if (gridSize < 4) {
+ gridSizeMenu.findItem(R.id.action_grid_size_4).isVisible = false
+ }
+ if (gridSize < 3) {
+ gridSizeMenu.findItem(R.id.action_grid_size_3).isVisible = false
+ }
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (handleGridSizeMenuItem(item)) {
+ return true
+ }
+ if (handleLayoutResType(item)) {
+ return true
+ }
+ if (handleSortOrderMenuItem(item)) {
+ return true
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+ private fun handleSortOrderMenuItem(
+ item: MenuItem
+ ): Boolean {
+ var sortOrder: String? = null
+
+ when (item.itemId) {
+ R.id.action_album_sort_order_asc -> sortOrder = AlbumSortOrder.ALBUM_A_Z
+ R.id.action_album_sort_order_desc -> sortOrder = AlbumSortOrder.ALBUM_Z_A
+ R.id.action_album_sort_order_artist -> sortOrder = AlbumSortOrder.ALBUM_ARTIST
+ R.id.action_album_sort_order_year -> sortOrder = AlbumSortOrder.ALBUM_YEAR
+ }
+ if (sortOrder != null) {
+ item.isChecked = true
+ setAndSaveSortOrder(sortOrder)
+ return true
+ }
+ return false
+ }
+
+ private fun handleLayoutResType(
+ item: MenuItem
+ ): Boolean {
+ var layoutRes = -1
+ when (item.itemId) {
+ R.id.action_layout_normal -> layoutRes = R.layout.item_grid
+ R.id.action_layout_card -> layoutRes = R.layout.item_card
+ R.id.action_layout_colored_card -> layoutRes = R.layout.item_card_color
+ R.id.action_layout_circular -> layoutRes = R.layout.item_grid_circle
+ R.id.action_layout_image -> layoutRes = R.layout.image
+ R.id.action_layout_gradient_image -> layoutRes = R.layout.item_image_gradient
+ }
+ if (layoutRes != -1) {
+ item.isChecked = true
+ setAndSaveLayoutRes(layoutRes)
+ return true
+ }
+ return false
+ }
+
+ private fun handleGridSizeMenuItem(
+ item: MenuItem
+ ): Boolean {
+ var gridSize = 0
+ when (item.itemId) {
+ R.id.action_grid_size_1 -> gridSize = 1
+ R.id.action_grid_size_2 -> gridSize = 2
+ R.id.action_grid_size_3 -> gridSize = 3
+ R.id.action_grid_size_4 -> gridSize = 4
+ R.id.action_grid_size_5 -> gridSize = 5
+ R.id.action_grid_size_6 -> gridSize = 6
+ R.id.action_grid_size_7 -> gridSize = 7
+ R.id.action_grid_size_8 -> gridSize = 8
+ }
+ if (gridSize > 0) {
+ item.isChecked = true
+ setAndSaveGridSize(gridSize)
+ return true
+ }
+ return false
+ }
+
}
interface AlbumClickListener {
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsFragment.kt
index 8fc574eba..877def068 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsFragment.kt
@@ -10,33 +10,43 @@ import android.view.View
import androidx.core.os.bundleOf
import androidx.core.text.HtmlCompat
import androidx.lifecycle.Observer
+import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.FragmentNavigatorExtras
import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
+import code.name.monkey.appthemehelper.ThemeStore
+import code.name.monkey.retromusic.EXTRA_ALBUM_ID
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.album.HorizontalAlbumAdapter
import code.name.monkey.retromusic.adapter.song.SimpleSongAdapter
import code.name.monkey.retromusic.dialogs.AddToPlaylistDialog
import code.name.monkey.retromusic.extensions.applyColor
+import code.name.monkey.retromusic.extensions.applyOutlineColor
import code.name.monkey.retromusic.extensions.show
import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.fragments.albums.AlbumClickListener
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.ArtistGlideRequest
-import code.name.monkey.retromusic.glide.RetroMusicColoredTarget
+import code.name.monkey.retromusic.glide.SingleColorTarget
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.model.Artist
+import code.name.monkey.retromusic.network.Result
import code.name.monkey.retromusic.network.model.LastFmArtist
+import code.name.monkey.retromusic.repository.RealRepository
import code.name.monkey.retromusic.util.CustomArtistImageUtil
import code.name.monkey.retromusic.util.MusicUtil
+import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.RetroUtil
-import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.fragment_artist_content.*
import kotlinx.android.synthetic.main.fragment_artist_details.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.viewModel
import org.koin.core.parameter.parametersOf
import java.util.*
@@ -66,13 +76,10 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
setupRecyclerView()
postponeEnterTransition()
detailsViewModel.getArtist().observe(viewLifecycleOwner, Observer {
-
showArtist(it)
startPostponedEnterTransition()
})
- detailsViewModel.getArtistInfo().observe(viewLifecycleOwner, Observer {
- artistInfo(it)
- })
+
playAction.apply {
setOnClickListener { MusicPlayerRemote.openQueue(artist.songs, 0, true) }
@@ -133,6 +140,7 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
albumTitle.text = albumText
songAdapter.swapDataSet(artist.songs.sortedBy { it.trackNumber })
artist.albums?.let { albumAdapter.swapDataSet(it) }
+
}
private fun loadBiography(
@@ -141,7 +149,14 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
) {
biography = null
this.lang = lang
- detailsViewModel.loadBiography(name, lang, null)
+ detailsViewModel.getArtistInfo(name, lang, null)
+ .observe(viewLifecycleOwner, Observer { result ->
+ when (result) {
+ is Result.Loading -> println("Loading")
+ is Result.Error -> println("Error")
+ is Result.Success -> artistInfo(result.data)
+ }
+ })
}
private fun artistInfo(lastFmArtist: LastFmArtist?) {
@@ -175,23 +190,26 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
private fun loadArtistImage(artist: Artist) {
ArtistGlideRequest.Builder.from(Glide.with(requireContext()), artist)
.generatePalette(requireContext()).build()
- .dontAnimate().into(object : RetroMusicColoredTarget(image) {
- override fun onColorReady(colors: MediaNotificationProcessor) {
- startPostponedEnterTransition()
- setColors(colors)
+ .dontAnimate()
+ .into(object : SingleColorTarget(image) {
+ override fun onColorReady(color: Int) {
+ setColors(color)
}
})
}
- private fun setColors(color: MediaNotificationProcessor) {
- shuffleAction.applyColor(color.backgroundColor)
- playAction.applyColor(color.backgroundColor)
+ private fun setColors(color: Int) {
+ val finalColor = if (PreferenceUtil.isAdaptiveColor) color
+ else ThemeStore.accentColor(requireContext())
+ shuffleAction.applyColor(finalColor)
+ playAction.applyOutlineColor(finalColor)
}
+
override fun onAlbumClick(albumId: Int, view: View) {
findNavController().navigate(
R.id.albumDetailsFragment,
- bundleOf("extra_album_id" to albumId),
+ bundleOf(EXTRA_ALBUM_ID to albumId),
null,
FragmentNavigatorExtras(
view to getString(R.string.transition_album_art)
@@ -216,7 +234,13 @@ class ArtistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_artist_d
return true
}
R.id.action_add_to_playlist -> {
- AddToPlaylistDialog.create(songs).show(childFragmentManager, "ADD_PLAYLIST")
+ lifecycleScope.launch(Dispatchers.IO) {
+ val playlists = get().fetchPlaylists()
+ withContext(Dispatchers.Main) {
+ AddToPlaylistDialog.create(playlists, songs)
+ .show(childFragmentManager, "ADD_PLAYLIST")
+ }
+ }
return true
}
R.id.action_set_artist_image -> {
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsViewModel.kt
index aa6613a4d..890397359 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsViewModel.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistDetailsViewModel.kt
@@ -1,51 +1,37 @@
package code.name.monkey.retromusic.fragments.artists
import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
+import androidx.lifecycle.liveData
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener
import code.name.monkey.retromusic.model.Artist
-import code.name.monkey.retromusic.repository.RealRepository
+import code.name.monkey.retromusic.network.Result
import code.name.monkey.retromusic.network.model.LastFmArtist
-import kotlinx.coroutines.Deferred
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.async
-import kotlinx.coroutines.launch
+import code.name.monkey.retromusic.repository.RealRepository
+import kotlinx.coroutines.Dispatchers.IO
class ArtistDetailsViewModel(
private val realRepository: RealRepository,
private val artistId: Int
) : ViewModel(), MusicServiceEventListener {
- private val loadArtistDetailsAsync: Deferred
- get() = viewModelScope.async(Dispatchers.IO) {
- realRepository.artistById(artistId)
- }
-
- private val _artist = MutableLiveData()
- private val _lastFmArtist = MutableLiveData()
-
- fun getArtist(): LiveData = _artist
- fun getArtistInfo(): LiveData = _lastFmArtist
-
- init {
- loadArtistDetails()
+ fun getArtist(): LiveData = liveData(IO) {
+ val artist = realRepository.artistById(artistId)
+ emit(artist)
}
- private fun loadArtistDetails() = viewModelScope.launch {
- val artist =
- loadArtistDetailsAsync.await() ?: throw NullPointerException("Album couldn't found")
- _artist.postValue(artist)
- }
-
- fun loadBiography(name: String, lang: String?, cache: String?) = viewModelScope.launch {
+ fun getArtistInfo(
+ name: String,
+ lang: String?,
+ cache: String?
+ ): LiveData> = liveData(IO) {
+ emit(Result.Loading)
val info = realRepository.artistInfo(name, lang, cache)
- _lastFmArtist.postValue(info)
+ emit(info)
}
override fun onMediaStoreChanged() {
- loadArtistDetails()
+ getArtist()
}
override fun onServiceConnected() {}
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistsFragment.kt
index 6f2d91a1a..b39909d33 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/artists/ArtistsFragment.kt
@@ -1,7 +1,7 @@
package code.name.monkey.retromusic.fragments.artists
import android.os.Bundle
-import android.view.View
+import android.view.*
import android.widget.ImageView
import androidx.core.os.bundleOf
import androidx.lifecycle.Observer
@@ -12,21 +12,17 @@ import code.name.monkey.retromusic.adapter.artist.ArtistAdapter
import code.name.monkey.retromusic.extensions.findActivityNavController
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
-import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
+import code.name.monkey.retromusic.helper.SortOrder.ArtistSortOrder
import code.name.monkey.retromusic.util.PreferenceUtil
+import code.name.monkey.retromusic.util.RetroUtil
-class ArtistsFragment :
- AbsRecyclerViewCustomGridSizeFragment(),
- MainActivityFragmentCallbacks, ArtistClickListener {
-
- override fun handleBackPress(): Boolean {
- return false
- }
+class ArtistsFragment : AbsRecyclerViewCustomGridSizeFragment(),
+ ArtistClickListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- libraryViewModel.artistsLiveData.observe(viewLifecycleOwner, Observer {
+ libraryViewModel.getArtists().observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
else
@@ -104,6 +100,161 @@ class ArtistsFragment :
val controller = findActivityNavController(R.id.fragment_container)
controller.navigate(R.id.artistDetailsFragment, bundleOf(EXTRA_ARTIST_ID to artistId))
}
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ val gridSizeItem: MenuItem = menu.findItem(R.id.action_grid_size)
+ if (RetroUtil.isLandscape()) {
+ gridSizeItem.setTitle(R.string.action_grid_size_land)
+ }
+ setUpGridSizeMenu(gridSizeItem.subMenu)
+ val layoutItem = menu.findItem(R.id.action_layout_type)
+ setupLayoutMenu(layoutItem.subMenu)
+ setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
+ super.onCreateOptionsMenu(menu, inflater)
+ }
+
+ private fun setUpSortOrderMenu(
+ sortOrderMenu: SubMenu
+ ) {
+ val currentSortOrder: String? = getSortOrder()
+ sortOrderMenu.clear()
+ sortOrderMenu.add(
+ 0,
+ R.id.action_artist_sort_order_asc,
+ 0,
+ R.string.sort_order_a_z
+ ).isChecked = currentSortOrder.equals(ArtistSortOrder.ARTIST_A_Z)
+ sortOrderMenu.add(
+ 0,
+ R.id.action_artist_sort_order_desc,
+ 1,
+ R.string.sort_order_z_a
+ ).isChecked = currentSortOrder.equals(ArtistSortOrder.ARTIST_Z_A)
+ sortOrderMenu.setGroupCheckable(0, true, true)
+ }
+
+ private fun setupLayoutMenu(
+ subMenu: SubMenu
+ ) {
+ when (itemLayoutRes()) {
+ R.layout.item_card -> subMenu.findItem(R.id.action_layout_card).isChecked = true
+ R.layout.item_grid -> subMenu.findItem(R.id.action_layout_normal).isChecked = true
+ R.layout.item_card_color ->
+ subMenu.findItem(R.id.action_layout_colored_card).isChecked = true
+ R.layout.item_grid_circle ->
+ subMenu.findItem(R.id.action_layout_circular).isChecked = true
+ R.layout.image -> subMenu.findItem(R.id.action_layout_image).isChecked = true
+ R.layout.item_image_gradient ->
+ subMenu.findItem(R.id.action_layout_gradient_image).isChecked = true
+ }
+ }
+
+ private fun setUpGridSizeMenu(
+ gridSizeMenu: SubMenu
+ ) {
+ when (getGridSize()) {
+ 1 -> gridSizeMenu.findItem(R.id.action_grid_size_1).isChecked =
+ true
+ 2 -> gridSizeMenu.findItem(R.id.action_grid_size_2).isChecked = true
+ 3 -> gridSizeMenu.findItem(R.id.action_grid_size_3).isChecked = true
+ 4 -> gridSizeMenu.findItem(R.id.action_grid_size_4).isChecked = true
+ 5 -> gridSizeMenu.findItem(R.id.action_grid_size_5).isChecked = true
+ 6 -> gridSizeMenu.findItem(R.id.action_grid_size_6).isChecked = true
+ 7 -> gridSizeMenu.findItem(R.id.action_grid_size_7).isChecked = true
+ 8 -> gridSizeMenu.findItem(R.id.action_grid_size_8).isChecked = true
+ }
+ val gridSize: Int = maxGridSize
+ if (gridSize < 8) {
+ gridSizeMenu.findItem(R.id.action_grid_size_8).isVisible = false
+ }
+ if (gridSize < 7) {
+ gridSizeMenu.findItem(R.id.action_grid_size_7).isVisible = false
+ }
+ if (gridSize < 6) {
+ gridSizeMenu.findItem(R.id.action_grid_size_6).isVisible = false
+ }
+ if (gridSize < 5) {
+ gridSizeMenu.findItem(R.id.action_grid_size_5).isVisible = false
+ }
+ if (gridSize < 4) {
+ gridSizeMenu.findItem(R.id.action_grid_size_4).isVisible = false
+ }
+ if (gridSize < 3) {
+ gridSizeMenu.findItem(R.id.action_grid_size_3).isVisible = false
+ }
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (handleGridSizeMenuItem(item)) {
+ return true
+ }
+ if (handleLayoutResType(item)) {
+ return true
+ }
+ if (handleSortOrderMenuItem(item)) {
+ return true
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+ private fun handleSortOrderMenuItem(
+ item: MenuItem
+ ): Boolean {
+ var sortOrder: String? = null
+
+ when (item.itemId) {
+ R.id.action_artist_sort_order_asc -> sortOrder = ArtistSortOrder.ARTIST_A_Z
+ R.id.action_artist_sort_order_desc -> sortOrder = ArtistSortOrder.ARTIST_Z_A
+ }
+ if (sortOrder != null) {
+ item.isChecked = true
+ setAndSaveSortOrder(sortOrder)
+ return true
+ }
+ return false
+ }
+
+ private fun handleLayoutResType(
+ item: MenuItem
+ ): Boolean {
+ var layoutRes = -1
+ when (item.itemId) {
+ R.id.action_layout_normal -> layoutRes = R.layout.item_grid
+ R.id.action_layout_card -> layoutRes = R.layout.item_card
+ R.id.action_layout_colored_card -> layoutRes = R.layout.item_card_color
+ R.id.action_layout_circular -> layoutRes = R.layout.item_grid_circle
+ R.id.action_layout_image -> layoutRes = R.layout.image
+ R.id.action_layout_gradient_image -> layoutRes = R.layout.item_image_gradient
+ }
+ if (layoutRes != -1) {
+ item.isChecked = true
+ setAndSaveLayoutRes(layoutRes)
+ return true
+ }
+ return false
+ }
+
+ private fun handleGridSizeMenuItem(
+ item: MenuItem
+ ): Boolean {
+ var gridSize = 0
+ when (item.itemId) {
+ R.id.action_grid_size_1 -> gridSize = 1
+ R.id.action_grid_size_2 -> gridSize = 2
+ R.id.action_grid_size_3 -> gridSize = 3
+ R.id.action_grid_size_4 -> gridSize = 4
+ R.id.action_grid_size_5 -> gridSize = 5
+ R.id.action_grid_size_6 -> gridSize = 6
+ R.id.action_grid_size_7 -> gridSize = 7
+ R.id.action_grid_size_8 -> gridSize = 8
+ }
+ if (gridSize > 0) {
+ item.isChecked = true
+ setAndSaveGridSize(gridSize)
+ return true
+ }
+ return false
+ }
}
interface ArtistClickListener {
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt
index f37423fe2..59875b4fa 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/base/AbsPlayerFragment.kt
@@ -1,10 +1,9 @@
package code.name.monkey.retromusic.fragments.base
-import android.annotation.SuppressLint
import android.content.ContentUris
import android.content.Intent
+import android.graphics.drawable.Drawable
import android.media.MediaMetadataRetriever
-import android.os.AsyncTask
import android.os.Build
import android.os.Bundle
import android.provider.MediaStore
@@ -15,30 +14,40 @@ import android.widget.Toast
import androidx.annotation.LayoutRes
import androidx.appcompat.widget.Toolbar
import androidx.core.os.bundleOf
+import androidx.lifecycle.lifecycleScope
import androidx.navigation.findNavController
import code.name.monkey.retromusic.EXTRA_ALBUM_ID
import code.name.monkey.retromusic.EXTRA_ARTIST_ID
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.tageditor.AbsTagEditorActivity
import code.name.monkey.retromusic.activities.tageditor.SongTagEditorActivity
+import code.name.monkey.retromusic.db.PlaylistEntity
+import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.dialogs.*
import code.name.monkey.retromusic.extensions.hide
+import code.name.monkey.retromusic.extensions.whichFragment
import code.name.monkey.retromusic.fragments.LibraryViewModel
+import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.player.PlayerAlbumCoverFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
import code.name.monkey.retromusic.interfaces.PaletteColorHolder
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.lyrics.Lyrics
+import code.name.monkey.retromusic.repository.RealRepository
+import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.*
import kotlinx.android.synthetic.main.shadow_statusbar_toolbar.*
+import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.Dispatchers.Main
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+import org.koin.android.ext.android.get
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
import java.io.FileNotFoundException
abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragment(layout),
Toolbar.OnMenuItemClickListener, PaletteColorHolder, PlayerAlbumCoverFragment.Callbacks {
- private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null
- private var updateLyricsAsyncTask: AsyncTask<*, *, *>? = null
private var playerAlbumCoverFragment: PlayerAlbumCoverFragment? = null
protected val libraryViewModel by sharedViewModel()
@@ -64,7 +73,13 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
return true
}
R.id.action_add_to_playlist -> {
- AddToPlaylistDialog.create(song).show(childFragmentManager, "ADD_PLAYLIST")
+ lifecycleScope.launch(IO) {
+ val playlists = get().fetchPlaylists()
+ withContext(Main) {
+ AddToPlaylistDialog.create(playlists, song)
+ .show(childFragmentManager, "ADD_PLAYLIST")
+ }
+ }
return true
}
R.id.action_clear_playing_queue -> {
@@ -146,9 +161,6 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
return false
}
- protected open fun toggleFavorite(song: Song) {
- MusicUtil.toggleFavorite(requireActivity(), song)
- }
abstract fun playerToolbar(): Toolbar?
@@ -170,79 +182,70 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
updateLyrics()
}
- override fun onDestroyView() {
- if (updateIsFavoriteTask != null && !updateIsFavoriteTask!!.isCancelled) {
- updateIsFavoriteTask!!.cancel(true)
- }
- if (updateLyricsAsyncTask != null && !updateLyricsAsyncTask!!.isCancelled) {
- updateLyricsAsyncTask!!.cancel(true)
- }
- super.onDestroyView()
- }
-
- @SuppressLint("StaticFieldLeak")
- fun updateIsFavorite() {
- if (updateIsFavoriteTask != null) {
- updateIsFavoriteTask!!.cancel(false)
- }
- updateIsFavoriteTask = object : AsyncTask() {
- override fun doInBackground(vararg params: Song): Boolean {
- return MusicUtil.isFavorite(requireActivity(), params[0])
- }
-
- override fun onPostExecute(isFavorite: Boolean) {
- val res = if (isFavorite)
- R.drawable.ic_favorite
- else
- R.drawable.ic_favorite_border
-
- val drawable =
- RetroUtil.getTintedVectorDrawable(requireContext(), res, toolbarIconColor())
- if (playerToolbar() != null && playerToolbar()!!.menu.findItem(R.id.action_toggle_favorite) != null)
- playerToolbar()!!.menu.findItem(R.id.action_toggle_favorite).setIcon(drawable)
- .title =
- if (isFavorite) getString(R.string.action_remove_from_favorites) else getString(
- R.string.action_add_to_favorites
- )
- }
- }.execute(MusicPlayerRemote.currentSong)
- }
-
- @SuppressLint("StaticFieldLeak")
- private fun updateLyrics() {
- if (updateLyricsAsyncTask != null) updateLyricsAsyncTask!!.cancel(false)
-
- updateLyricsAsyncTask = object : AsyncTask() {
- override fun onPreExecute() {
- super.onPreExecute()
- setLyrics(null)
- }
-
- override fun doInBackground(vararg params: Song): Lyrics? {
- try {
- var data: String? =
- LyricUtil.getStringFromFile(params[0].title, params[0].artistName)
- return if (TextUtils.isEmpty(data)) {
- data = MusicUtil.getLyrics(params[0])
- return if (TextUtils.isEmpty(data)) {
- null
- } else {
- Lyrics.parse(params[0], data)
- }
- } else Lyrics.parse(params[0], data!!)
- } catch (err: FileNotFoundException) {
- return null
+ protected open fun toggleFavorite(song: Song) {
+ lifecycleScope.launch(IO) {
+ val playlist: PlaylistEntity? = libraryViewModel.favoritePlaylist()
+ if (playlist != null) {
+ val songEntity = song.toSongEntity(playlist.playListId)
+ val isFavorite = libraryViewModel.isFavoriteSong(songEntity).isNotEmpty()
+ if (isFavorite) {
+ libraryViewModel.removeSongFromPlaylist(songEntity)
+ } else {
+ libraryViewModel.insertSongs(listOf(song.toSongEntity(playlist.playListId)))
}
}
+ libraryViewModel.forceReload(ReloadType.Playlists)
+ requireContext().sendBroadcast(Intent(MusicService.FAVORITE_STATE_CHANGED))
+ }
+ }
- override fun onPostExecute(l: Lyrics?) {
- setLyrics(l)
+ fun updateIsFavorite() {
+ lifecycleScope.launch(IO) {
+ val playlist: PlaylistEntity? = libraryViewModel.favoritePlaylist()
+ if (playlist != null) {
+ val song: SongEntity =
+ MusicPlayerRemote.currentSong.toSongEntity(playlist.playListId)
+ val isFavorite: Boolean = libraryViewModel.isFavoriteSong(song).isNotEmpty()
+ withContext(Main) {
+ val icon =
+ if (isFavorite) R.drawable.ic_favorite else R.drawable.ic_favorite_border
+ val drawable: Drawable? = RetroUtil.getTintedVectorDrawable(
+ requireContext(),
+ icon,
+ toolbarIconColor()
+ )
+ if (playerToolbar() != null) {
+ playerToolbar()?.menu?.findItem(R.id.action_toggle_favorite)
+ ?.setIcon(drawable)?.title =
+ if (isFavorite) getString(R.string.action_remove_from_favorites)
+ else getString(R.string.action_add_to_favorites)
+ }
+ }
}
+ }
+ }
- override fun onCancelled(s: Lyrics?) {
- onPostExecute(null)
+ private fun updateLyrics() {
+ setLyrics(null)
+ lifecycleScope.launch(IO) {
+ val song = MusicPlayerRemote.currentSong
+ val lyrics = try {
+ var data: String? = LyricUtil.getStringFromFile(song.title, song.artistName)
+ if (TextUtils.isEmpty(data)) {
+ data = MusicUtil.getLyrics(song)
+ if (TextUtils.isEmpty(data)) {
+ null
+ } else {
+ Lyrics.parse(song, data)
+ }
+ } else Lyrics.parse(song, data!!)
+ } catch (err: FileNotFoundException) {
+ null
}
- }.execute(MusicPlayerRemote.currentSong)
+ withContext(Main) {
+ setLyrics(lyrics)
+ }
+ }
}
open fun setLyrics(l: Lyrics?) {
@@ -255,8 +258,7 @@ abstract class AbsPlayerFragment(@LayoutRes layout: Int) : AbsMainActivityFragme
) {
view.findViewById(R.id.status_bar).visibility = View.GONE
}
- playerAlbumCoverFragment =
- childFragmentManager.findFragmentById(R.id.playerAlbumCoverFragment) as PlayerAlbumCoverFragment?
+ playerAlbumCoverFragment = whichFragment(R.id.playerAlbumCoverFragment)
playerAlbumCoverFragment?.setCallbacks(this)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.java b/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.java
index 65ad534a3..4d5a0d099 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.java
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/folder/FoldersFragment.java
@@ -290,7 +290,7 @@ public class FoldersFragment extends AbsMainActivityFragment implements
}
}
if (startIndex > -1) {
- MusicPlayerRemote.INSTANCE.openQueue(songs, startIndex, true);
+ MusicPlayerRemote.openQueue(songs, startIndex, true);
} else {
final File finalFile = file1;
Snackbar.make(coordinatorLayout, Html.fromHtml(
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenreDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenreDetailsFragment.kt
index 8924ffd94..fef2df722 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenreDetailsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenreDetailsFragment.kt
@@ -36,7 +36,7 @@ class GenreDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playlist_
mainActivity.addMusicServiceEventListener(detailsViewModel)
mainActivity.setSupportActionBar(toolbar)
mainActivity.hideBottomBarVisibility(false)
-
+ progressIndicator.hide()
setupRecyclerView()
detailsViewModel.getSongs().observe(viewLifecycleOwner, androidx.lifecycle.Observer {
songs(it)
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenresFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenresFragment.kt
index e4017e573..568da54ae 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenresFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/genres/GenresFragment.kt
@@ -21,18 +21,12 @@ import androidx.recyclerview.widget.LinearLayoutManager
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.GenreAdapter
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewFragment
-import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
-class GenresFragment : AbsRecyclerViewFragment(),
- MainActivityFragmentCallbacks {
-
- override fun handleBackPress(): Boolean {
- return false
- }
+class GenresFragment : AbsRecyclerViewFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- libraryViewModel.genresLiveData.observe(viewLifecycleOwner, Observer {
+ libraryViewModel.getGenre().observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
else
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt
index be901a82e..460731af4 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/home/HomeFragment.kt
@@ -16,50 +16,36 @@ package code.name.monkey.retromusic.fragments.home
import android.app.ActivityOptions
import android.os.Bundle
-import android.util.DisplayMetrics
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.MenuItem.SHOW_AS_ACTION_IF_ROOM
import android.view.View
import androidx.core.os.bundleOf
import androidx.lifecycle.Observer
-import androidx.lifecycle.lifecycleScope
-import androidx.navigation.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
-import code.name.monkey.retromusic.EXTRA_PLAYLIST
+import code.name.monkey.retromusic.HISTORY_PLAYLIST
+import code.name.monkey.retromusic.LAST_ADDED_PLAYLIST
import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.TOP_PLAYED_PLAYLIST
import code.name.monkey.retromusic.adapter.HomeAdapter
import code.name.monkey.retromusic.extensions.findActivityNavController
import code.name.monkey.retromusic.fragments.LibraryViewModel
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.glide.ProfileBannerGlideRequest
import code.name.monkey.retromusic.glide.UserProfileGlideRequest
-import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.model.smartplaylist.HistoryPlaylist
-import code.name.monkey.retromusic.model.smartplaylist.LastAddedPlaylist
-import code.name.monkey.retromusic.model.smartplaylist.TopTracksPlaylist
-import code.name.monkey.retromusic.repository.Repository
import code.name.monkey.retromusic.util.NavigationUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.abs_playlists.*
import kotlinx.android.synthetic.main.fragment_banner_home.*
import kotlinx.android.synthetic.main.home_content.*
-import kotlinx.coroutines.launch
-import org.koin.android.ext.android.inject
import org.koin.androidx.viewmodel.ext.android.sharedViewModel
class HomeFragment :
AbsMainActivityFragment(if (PreferenceUtil.isHomeBanner) R.layout.fragment_banner_home else R.layout.fragment_home) {
- private val repository by inject()
private val libraryViewModel: LibraryViewModel by sharedViewModel()
- private val displayMetrics: DisplayMetrics
- get() {
- val display = mainActivity.windowManager.defaultDisplay
- val metrics = DisplayMetrics()
- display.getMetrics(metrics)
- return metrics
- }
-
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setStatusBarColorAuto(view)
@@ -74,31 +60,26 @@ class HomeFragment :
lastAdded.setOnClickListener {
findActivityNavController(R.id.fragment_container).navigate(
- R.id.playlistDetailsFragment,
- bundleOf(EXTRA_PLAYLIST to LastAddedPlaylist())
+ R.id.detailListFragment,
+ bundleOf("type" to LAST_ADDED_PLAYLIST)
)
}
topPlayed.setOnClickListener {
findActivityNavController(R.id.fragment_container).navigate(
- R.id.playlistDetailsFragment,
- bundleOf(EXTRA_PLAYLIST to TopTracksPlaylist())
+ R.id.detailListFragment,
+ bundleOf("type" to TOP_PLAYED_PLAYLIST)
)
}
actionShuffle.setOnClickListener {
- lifecycleScope.launch {
- MusicPlayerRemote.openAndShuffleQueue(
- repository.allSongs(),
- true
- )
- }
+ libraryViewModel.shuffleSongs()
}
history.setOnClickListener {
- requireActivity().findNavController(R.id.fragment_container).navigate(
- R.id.playlistDetailsFragment,
- bundleOf(EXTRA_PLAYLIST to HistoryPlaylist())
+ findActivityNavController(R.id.fragment_container).navigate(
+ R.id.detailListFragment,
+ bundleOf("type" to HISTORY_PLAYLIST)
)
}
@@ -118,7 +99,7 @@ class HomeFragment :
adapter = homeAdapter
}
- libraryViewModel.homeLiveData.observe(viewLifecycleOwner, Observer {
+ libraryViewModel.getHome().observe(viewLifecycleOwner, Observer {
homeAdapter.swapData(it)
})
@@ -138,6 +119,14 @@ class HomeFragment :
).build().into(userImage)
}
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ super.onCreateOptionsMenu(menu, inflater)
+ menu.removeItem(R.id.action_grid_size)
+ menu.removeItem(R.id.action_layout_type)
+ menu.removeItem(R.id.action_sort_order)
+ menu.findItem(R.id.action_settings).setShowAsAction(SHOW_AS_ACTION_IF_ROOM)
+ }
+
companion object {
const val TAG: String = "BannerHomeFragment"
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/library/LibraryFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/library/LibraryFragment.kt
index 41d40f09e..086e0a09b 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/library/LibraryFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/library/LibraryFragment.kt
@@ -4,21 +4,26 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
+import androidx.core.text.HtmlCompat
import androidx.navigation.fragment.findNavController
import androidx.navigation.ui.NavigationUI
+import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.common.ATHToolbarActivity.getToolbarBackgroundColor
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.dialogs.CreatePlaylistDialog
+import code.name.monkey.retromusic.dialogs.ImportPlaylistDialog
import code.name.monkey.retromusic.extensions.findNavController
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
-import com.google.android.material.appbar.AppBarLayout
import kotlinx.android.synthetic.main.fragment_library.*
+import java.lang.String
class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
setHasOptionsMenu(true)
+ retainInstance = true
mainActivity.hideBottomBarVisibility(true)
mainActivity.setSupportActionBar(toolbar)
mainActivity.supportActionBar?.title = null
@@ -30,6 +35,17 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
)
}
setupNavigationController()
+ setupTitle()
+ }
+
+ private fun setupTitle() {
+ val color = ThemeStore.accentColor(requireContext())
+ val hexColor = String.format("#%06X", 0xFFFFFF and color)
+ val appName = HtmlCompat.fromHtml(
+ "Retro Music",
+ HtmlCompat.FROM_HTML_MODE_COMPACT
+ )
+ appNameText.text = appName
}
private fun setupNavigationController() {
@@ -60,19 +76,15 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) {
null,
navOptions
)
+ R.id.action_import_playlist -> ImportPlaylistDialog().show(
+ childFragmentManager,
+ "ImportPlaylist"
+ )
+ R.id.action_add_to_playlist -> CreatePlaylistDialog.create(emptyList()).show(
+ childFragmentManager,
+ "ShowCreatePlaylistDialog"
+ )
}
return super.onOptionsItemSelected(item)
}
-
- fun addOnAppBarOffsetChangedListener(changedListener: AppBarLayout.OnOffsetChangedListener) {
- appBarLayout.addOnOffsetChangedListener(changedListener)
- }
-
- fun removeOnAppBarOffsetChangedListener(changedListener: AppBarLayout.OnOffsetChangedListener) {
- appBarLayout.removeOnOffsetChangedListener(changedListener)
- }
-
- fun getTotalAppBarScrollingRange(): Int {
- return 0
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt
index 323c89b4e..c4748128b 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/classic/ClassicPlayerFragment.kt
@@ -20,7 +20,6 @@ import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.RetroBottomSheetBehavior
-import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.show
@@ -69,9 +68,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
- (requireActivity() as AbsSlidingMusicPanelActivity).getBottomSheetBehavior()
- .setAllowDragging(false)
-
+ mainActivity.getBottomSheetBehavior().setAllowDragging(false)
playerQueueSheet.setContentPadding(
playerQueueSheet.contentPaddingLeft,
(slideOffset * status_bar.height).toInt(),
@@ -83,18 +80,17 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
- val activity = requireActivity() as AbsSlidingMusicPanelActivity
when (newState) {
BottomSheetBehavior.STATE_EXPANDED,
BottomSheetBehavior.STATE_DRAGGING -> {
- activity.getBottomSheetBehavior().setAllowDragging(false)
+ mainActivity.getBottomSheetBehavior().setAllowDragging(false)
}
BottomSheetBehavior.STATE_COLLAPSED -> {
resetToCurrentPosition()
- activity.getBottomSheetBehavior().setAllowDragging(true)
+ mainActivity.getBottomSheetBehavior().setAllowDragging(true)
}
else -> {
- activity.getBottomSheetBehavior().setAllowDragging(true)
+ mainActivity.getBottomSheetBehavior().setAllowDragging(true)
}
}
}
@@ -132,8 +128,7 @@ class ClassicPlayerFragment : AbsPlayerFragment(R.layout.fragment_classic_player
playerQueueSheet.background = shapeDrawable
playerQueueSheet.setOnTouchListener { _, _ ->
- (requireActivity() as AbsSlidingMusicPanelActivity).getBottomSheetBehavior()
- .setAllowDragging(false)
+ mainActivity.getBottomSheetBehavior().setAllowDragging(false)
getQueuePanel().setAllowDragging(true)
return@setOnTouchListener false
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/fit/FitPlaybackControlsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/fit/FitPlaybackControlsFragment.kt
index cf3bb2f63..fb31aa31a 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/fit/FitPlaybackControlsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/fit/FitPlaybackControlsFragment.kt
@@ -3,9 +3,7 @@ package code.name.monkey.retromusic.fragments.player.fit
import android.animation.ObjectAnimator
import android.graphics.PorterDuff
import android.os.Bundle
-import android.view.LayoutInflater
import android.view.View
-import android.view.ViewGroup
import android.view.animation.AccelerateInterpolator
import android.view.animation.DecelerateInterpolator
import android.view.animation.LinearInterpolator
@@ -26,7 +24,6 @@ import code.name.monkey.retromusic.helper.PlayPauseButtonOnClickHandler
import code.name.monkey.retromusic.misc.SimpleOnSeekbarChangeListener
import code.name.monkey.retromusic.service.MusicService
import code.name.monkey.retromusic.util.MusicUtil
-
import code.name.monkey.retromusic.util.PreferenceUtil
import code.name.monkey.retromusic.util.color.MediaNotificationProcessor
import kotlinx.android.synthetic.main.fragment_fit_playback_controls.*
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt
index f51b1c75d..0eacbb9ad 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/player/gradient/GradientPlayerFragment.kt
@@ -5,7 +5,6 @@ import android.annotation.SuppressLint
import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.PorterDuff
-import android.os.AsyncTask
import android.os.Bundle
import android.view.View
import android.view.animation.LinearInterpolator
@@ -18,10 +17,8 @@ import androidx.core.view.ViewCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.appthemehelper.util.ColorUtil
-import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.RetroBottomSheetBehavior
-import code.name.monkey.retromusic.activities.base.AbsSlidingMusicPanelActivity
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
import code.name.monkey.retromusic.extensions.hide
import code.name.monkey.retromusic.extensions.ripAlpha
@@ -62,14 +59,11 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
private var recyclerViewSwipeManager: RecyclerViewSwipeManager? = null
private var recyclerViewTouchActionGuardManager: RecyclerViewTouchActionGuardManager? = null
private var playingQueueAdapter: PlayingQueueAdapter? = null
- private var updateIsFavoriteTask: AsyncTask<*, *, *>? = null
private lateinit var linearLayoutManager: LinearLayoutManager
private val bottomSheetCallbackList = object : BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
- (requireActivity() as AbsSlidingMusicPanelActivity).getBottomSheetBehavior()
- .setAllowDragging(false)
-
+ mainActivity.getBottomSheetBehavior().setAllowDragging(false)
playerQueueSheet.setPadding(
playerQueueSheet.paddingLeft,
(slideOffset * status_bar.height).toInt(),
@@ -79,18 +73,17 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
- val activity = requireActivity() as AbsSlidingMusicPanelActivity
when (newState) {
BottomSheetBehavior.STATE_EXPANDED,
BottomSheetBehavior.STATE_DRAGGING -> {
- activity.getBottomSheetBehavior().setAllowDragging(false)
+ mainActivity.getBottomSheetBehavior().setAllowDragging(false)
}
BottomSheetBehavior.STATE_COLLAPSED -> {
resetToCurrentPosition()
- activity.getBottomSheetBehavior().setAllowDragging(true)
+ mainActivity.getBottomSheetBehavior().setAllowDragging(true)
}
else -> {
- activity.getBottomSheetBehavior().setAllowDragging(true)
+ mainActivity.getBottomSheetBehavior().setAllowDragging(true)
}
}
}
@@ -139,8 +132,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
private fun setupSheet() {
getQueuePanel().addBottomSheetCallback(bottomSheetCallbackList)
playerQueueSheet.setOnTouchListener { _, _ ->
- (requireActivity() as AbsSlidingMusicPanelActivity).getBottomSheetBehavior()
- .setAllowDragging(false)
+ mainActivity.getBottomSheetBehavior().setAllowDragging(false)
getQueuePanel().setAllowDragging(true)
return@setOnTouchListener false
}
@@ -159,7 +151,6 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
recyclerViewDragDropManager?.cancelDrag()
super.onPause()
progressViewUpdateHelper.stop()
-
}
override fun playerToolbar(): Toolbar? {
@@ -224,9 +215,8 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
override fun toggleFavorite(song: Song) {
super.toggleFavorite(song)
- MusicUtil.toggleFavorite(requireContext(), song)
if (song.id == MusicPlayerRemote.currentSong.id) {
- updateFavorite()
+ updateIsFavorite()
}
}
@@ -274,6 +264,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
override fun onQueueChanged() {
super.onQueueChanged()
updateLabel()
+ playingQueueAdapter?.swapDataSet(MusicPlayerRemote.playingQueue)
}
private fun updateSong() {
@@ -372,7 +363,7 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
} else {
val title = MusicPlayerRemote.playingQueue[MusicPlayerRemote.position + 1].title
nextSong.apply {
- text = "Next: $title"
+ text = title
show()
}
}
@@ -478,36 +469,4 @@ class GradientPlayerFragment : AbsPlayerFragment(R.layout.fragment_gradient_play
songTotalTime.text = MusicUtil.getReadableDurationString(total.toLong())
songCurrentProgress.text = MusicUtil.getReadableDurationString(progress.toLong())
}
-
- @SuppressLint("StaticFieldLeak")
- private fun updateFavorite() {
- if (updateIsFavoriteTask != null) {
- updateIsFavoriteTask?.cancel(false)
- }
- updateIsFavoriteTask =
- object : AsyncTask() {
- override fun doInBackground(vararg params: Song): Boolean? {
- val activity = activity
- return if (activity != null) {
- MusicUtil.isFavorite(requireActivity(), params[0])
- } else {
- cancel(false)
- null
- }
- }
-
- override fun onPostExecute(isFavorite: Boolean?) {
- val activity = activity
- if (activity != null) {
- val res = if (isFavorite!!)
- R.drawable.ic_favorite
- else
- R.drawable.ic_favorite_border
-
- val drawable = TintHelper.createTintedDrawable(activity, res, Color.WHITE)
- songFavourite?.setImageDrawable(drawable)
- }
- }
- }.execute(MusicPlayerRemote.currentSong)
- }
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/ImportPlaylistFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/ImportPlaylistFragment.kt
new file mode 100644
index 000000000..efe3c4e40
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/ImportPlaylistFragment.kt
@@ -0,0 +1,72 @@
+package code.name.monkey.retromusic.fragments.playlists
+
+import android.os.Bundle
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.View
+import android.widget.Toast
+import androidx.lifecycle.Observer
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.LinearLayoutManager
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.adapter.playlist.LegacyPlaylistAdapter
+import code.name.monkey.retromusic.db.PlaylistEntity
+import code.name.monkey.retromusic.fragments.ReloadType.Playlists
+import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewFragment
+import code.name.monkey.retromusic.model.Playlist
+import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.launch
+
+class ImportPlaylistFragment :
+ AbsRecyclerViewFragment(),
+ LegacyPlaylistAdapter.PlaylistClickListener {
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ libraryViewModel.getLegacyPlaylist().observe(viewLifecycleOwner, Observer {
+ if (it.isNotEmpty())
+ adapter?.swapData(it)
+ else
+ adapter?.swapData(listOf())
+ })
+ }
+
+ override fun createLayoutManager(): LinearLayoutManager {
+ return LinearLayoutManager(requireContext())
+ }
+
+ override fun createAdapter(): LegacyPlaylistAdapter {
+ return LegacyPlaylistAdapter(
+ requireActivity(),
+ ArrayList(),
+ R.layout.item_list_no_image,
+ this
+ )
+ }
+
+ override fun onPlaylistClick(playlist: Playlist) {
+ Toast.makeText(requireContext(), "Importing ${playlist.name}", Toast.LENGTH_LONG).show()
+ lifecycleScope.launch(IO) {
+ if (playlist.name.isNotEmpty()) {
+ if (libraryViewModel.checkPlaylistExists(playlist.name).isEmpty()) {
+ val playlistId: Long =
+ libraryViewModel.createPlaylist(PlaylistEntity(playlist.name))
+ libraryViewModel.insertSongs(playlist.getSongs().map {
+ it.toSongEntity(playlistId.toInt())
+ })
+ libraryViewModel.forceReload(Playlists)
+ } else {
+ Toast.makeText(requireContext(), "Playlist exists", Toast.LENGTH_SHORT)
+ .show()
+ }
+ }
+ }
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ menu.removeItem(R.id.action_grid_size)
+ menu.removeItem(R.id.action_layout_type)
+ menu.removeItem(R.id.action_sort_order)
+ super.onCreateOptionsMenu(menu, inflater)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt
index 5c2d989bb..8f78f5185 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsFragment.kt
@@ -5,18 +5,17 @@ import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
-import androidx.lifecycle.Observer
import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.OrderablePlaylistSongAdapter
import code.name.monkey.retromusic.adapter.song.SongAdapter
+import code.name.monkey.retromusic.db.PlaylistWithSongs
+import code.name.monkey.retromusic.db.toSongs
import code.name.monkey.retromusic.extensions.dipToPix
import code.name.monkey.retromusic.fragments.base.AbsMainActivityFragment
import code.name.monkey.retromusic.helper.menu.PlaylistMenuHelper
-import code.name.monkey.retromusic.model.AbsCustomPlaylist
-import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.util.PlaylistsUtil
import com.h6ah4i.android.widget.advrecyclerview.animator.RefactoredDefaultItemAnimator
@@ -32,7 +31,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
parametersOf(arguments.extraPlaylist)
}
- private lateinit var playlist: Playlist
+ private lateinit var playlist: PlaylistWithSongs
private lateinit var adapter: SongAdapter
private var wrappedAdapter: RecyclerView.Adapter<*>? = null
@@ -46,28 +45,23 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
mainActivity.hideBottomBarVisibility(false)
playlist = arguments.extraPlaylist
+ toolbar.title = playlist.playlistEntity.playlistName
setUpRecyclerView()
- viewModel.getSongs().observe(viewLifecycleOwner, Observer {
- songs(it)
- })
-
- viewModel.getPlaylist().observe(viewLifecycleOwner, Observer {
- playlist = it
- toolbar.title = it.name
+ viewModel.getSongs().observe(viewLifecycleOwner, {
+ songs(it.toSongs())
})
}
private fun setUpRecyclerView() {
recyclerView.layoutManager = LinearLayoutManager(requireContext())
- if (playlist is AbsCustomPlaylist) {
- adapter = SongAdapter(requireActivity(), ArrayList(), R.layout.item_list, null)
- recyclerView.adapter = adapter
- } else {
- recyclerViewDragDropManager = RecyclerViewDragDropManager()
- val animator = RefactoredDefaultItemAnimator()
- adapter = OrderablePlaylistSongAdapter(requireActivity(),
+ recyclerViewDragDropManager = RecyclerViewDragDropManager()
+ val animator = RefactoredDefaultItemAnimator()
+ adapter =
+ OrderablePlaylistSongAdapter(
+ playlist.playlistEntity,
+ requireActivity(),
ArrayList(),
R.layout.item_list,
null,
@@ -75,7 +69,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
override fun onMoveItem(fromPosition: Int, toPosition: Int) {
if (PlaylistsUtil.moveItem(
requireContext(),
- playlist.id,
+ playlist.playlistEntity.playListId,
fromPosition,
toPosition
)
@@ -86,13 +80,13 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
}
}
})
- wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(adapter)
+ wrappedAdapter = recyclerViewDragDropManager!!.createWrappedAdapter(adapter)
- recyclerView.adapter = wrappedAdapter
- recyclerView.itemAnimator = animator
+ recyclerView.adapter = wrappedAdapter
+ recyclerView.itemAnimator = animator
+
+ recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
- recyclerViewDragDropManager?.attachRecyclerView(recyclerView)
- }
adapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
override fun onChanged() {
super.onChanged()
@@ -103,9 +97,9 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
- val menuRes = if (playlist is AbsCustomPlaylist)
+ val menuRes =/* if (playlist is AbsCustomPlaylist)
R.menu.menu_smart_playlist_detail
- else R.menu.menu_playlist_detail
+ else*/ R.menu.menu_playlist_detail
inflater.inflate(menuRes, menu)
}
@@ -129,7 +123,7 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
return String(Character.toChars(unicode))
}
- public override fun onPause() {
+ override fun onPause() {
if (recyclerViewDragDropManager != null) {
recyclerViewDragDropManager!!.cancelDrag()
}
@@ -160,11 +154,11 @@ class PlaylistDetailsFragment : AbsMainActivityFragment(R.layout.fragment_playli
}
fun songs(songs: List) {
+ progressIndicator.hide()
if (songs.isNotEmpty()) {
adapter.swapDataSet(songs)
} else {
showEmptyView()
}
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsViewModel.kt
index de61bdebb..ac498b4e2 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsViewModel.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistDetailsViewModel.kt
@@ -3,42 +3,29 @@ package code.name.monkey.retromusic.fragments.playlists
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.viewModelScope
-import code.name.monkey.retromusic.App
+import code.name.monkey.retromusic.db.PlaylistWithSongs
+import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.interfaces.MusicServiceEventListener
-import code.name.monkey.retromusic.model.AbsCustomPlaylist
-import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.repository.RealRepository
-import code.name.monkey.retromusic.util.PlaylistsUtil
-import kotlinx.coroutines.Dispatchers.Main
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
class PlaylistDetailsViewModel(
private val realRepository: RealRepository,
- private var playlist: Playlist
+ private var playlist: PlaylistWithSongs
) : ViewModel(), MusicServiceEventListener {
+
private val _playListSongs = MutableLiveData>()
- private val _playlist = MutableLiveData().apply {
+ private val _playlist = MutableLiveData().apply {
postValue(playlist)
}
- fun getPlaylist(): LiveData = _playlist
+ fun getPlaylist(): LiveData = _playlist
- fun getSongs(): LiveData> = _playListSongs
+ fun getSongs(): LiveData> = realRepository.playlistSongs(playlist.playlistEntity)
- init {
- loadPlaylistSongs(playlist)
- }
-
- private fun loadPlaylistSongs(playlist: Playlist) = viewModelScope.launch {
- val songs = realRepository.getPlaylistSongs(playlist)
- withContext(Main) { _playListSongs.postValue(songs) }
- }
override fun onMediaStoreChanged() {
- if (playlist !is AbsCustomPlaylist) {
+ /*if (playlist !is AbsCustomPlaylist) {
// Playlist deleted
if (!PlaylistsUtil.doesPlaylistExist(App.getContext(), playlist.id)) {
//TODO Finish the page
@@ -54,7 +41,7 @@ class PlaylistDetailsViewModel(
}
}
}
- loadPlaylistSongs(playlist)
+ loadPlaylistSongs(playlist)*/
}
override fun onServiceConnected() {}
@@ -64,4 +51,4 @@ class PlaylistDetailsViewModel(
override fun onPlayStateChanged() {}
override fun onRepeatModeChanged() {}
override fun onShuffleModeChanged() {}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt
index 226817155..95f849a2a 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/playlists/PlaylistsFragment.kt
@@ -1,25 +1,23 @@
package code.name.monkey.retromusic.fragments.playlists
import android.os.Bundle
+import android.view.Menu
+import android.view.MenuInflater
+import android.view.MenuItem
import android.view.View
import androidx.lifecycle.Observer
-import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.LinearLayoutManager
+import code.name.monkey.appthemehelper.util.ToolbarContentTintHelper
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.playlist.PlaylistAdapter
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewFragment
-import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
+import kotlinx.android.synthetic.main.fragment_library.*
-class PlaylistsFragment :
- AbsRecyclerViewFragment(),
- MainActivityFragmentCallbacks {
-
- override fun handleBackPress(): Boolean {
- return false
- }
+class PlaylistsFragment : AbsRecyclerViewFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- libraryViewModel.playlisitsLiveData.observe(viewLifecycleOwner, Observer {
+ libraryViewModel.getPlaylists().observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
else
@@ -30,8 +28,8 @@ class PlaylistsFragment :
override val emptyMessage: Int
get() = R.string.no_playlists
- override fun createLayoutManager(): GridLayoutManager {
- return GridLayoutManager(requireContext(), 1)
+ override fun createLayoutManager(): LinearLayoutManager {
+ return LinearLayoutManager(requireContext())
}
override fun createAdapter(): PlaylistAdapter {
@@ -43,9 +41,18 @@ class PlaylistsFragment :
)
}
- companion object {
- fun newInstance(): PlaylistsFragment {
- return PlaylistsFragment()
- }
+ override fun onPrepareOptionsMenu(menu: Menu) {
+ super.onPrepareOptionsMenu(menu)
+ ToolbarContentTintHelper.handleOnPrepareOptionsMenu(requireActivity(), toolbar)
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ menu.removeItem(R.id.action_grid_size)
+ menu.removeItem(R.id.action_layout_type)
+ menu.removeItem(R.id.action_sort_order)
+ menu.add(0, R.id.action_add_to_playlist, 0, R.string.new_playlist_title)
+ menu.add(0, R.id.action_import_playlist, 0, R.string.import_playlist)
+ menu.findItem(R.id.action_settings).setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER)
+ super.onCreateOptionsMenu(menu, inflater)
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/queue/PlayingQueueFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/queue/PlayingQueueFragment.kt
index f829f985c..6376420c9 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/queue/PlayingQueueFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/queue/PlayingQueueFragment.kt
@@ -22,7 +22,6 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.PlayingQueueAdapter
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewFragment
import code.name.monkey.retromusic.helper.MusicPlayerRemote
-import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
import com.h6ah4i.android.widget.advrecyclerview.animator.DraggableItemAnimator
import com.h6ah4i.android.widget.advrecyclerview.draggable.RecyclerViewDragDropManager
import com.h6ah4i.android.widget.advrecyclerview.swipeable.RecyclerViewSwipeManager
@@ -33,13 +32,7 @@ import kotlinx.android.synthetic.main.activity_playing_queue.*
/**
* Created by hemanths on 2019-12-08.
*/
-class PlayingQueueFragment :
- AbsRecyclerViewFragment(),
- MainActivityFragmentCallbacks {
-
- override fun handleBackPress(): Boolean {
- return false
- }
+class PlayingQueueFragment : AbsRecyclerViewFragment() {
private lateinit var wrappedAdapter: RecyclerView.Adapter<*>
private var recyclerViewDragDropManager: RecyclerViewDragDropManager? = null
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/search/SearchViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/search/SearchViewModel.kt
index eecff933c..506810236 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/search/SearchViewModel.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/search/SearchViewModel.kt
@@ -6,9 +6,7 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import code.name.monkey.retromusic.repository.RealRepository
import kotlinx.coroutines.Dispatchers.IO
-import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch
-import kotlinx.coroutines.withContext
class SearchViewModel(private val realRepository: RealRepository) : ViewModel() {
private val results = MutableLiveData>()
@@ -17,6 +15,6 @@ class SearchViewModel(private val realRepository: RealRepository) : ViewModel()
fun search(query: String?) = viewModelScope.launch(IO) {
val result = realRepository.search(query)
- withContext(Main) { results.postValue(result) }
+ results.value = result
}
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/MainSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/MainSettingsFragment.kt
index d0c15861d..2b4e8a07a 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/MainSettingsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/MainSettingsFragment.kt
@@ -63,7 +63,7 @@ class MainSettingsFragment : Fragment(), View.OnClickListener {
aboutSettings.setOnClickListener(this)
buyProContainer.apply {
- if (!App.isProVersion()) show() else hide()
+ if (App.isProVersion()) hide() else show()
setOnClickListener {
NavigationUtil.goToProVersion(requireContext())
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/OtherSettingsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/OtherSettingsFragment.kt
index 2338c6f7e..c52d4adb4 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/settings/OtherSettingsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/settings/OtherSettingsFragment.kt
@@ -19,12 +19,16 @@ import android.view.View
import androidx.preference.Preference
import code.name.monkey.appthemehelper.common.prefs.supportv7.ATEListPreference
import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.fragments.LibraryViewModel
+import code.name.monkey.retromusic.fragments.ReloadType.HomeSections
+import org.koin.androidx.viewmodel.ext.android.sharedViewModel
/**
* @author Hemanth S (h4h13).
*/
class OtherSettingsFragment : AbsSettingsFragment() {
+ private val libraryViewModel by sharedViewModel()
override fun invalidateSettings() {
val languagePreference: ATEListPreference? = findPreference("language_name")
languagePreference?.setOnPreferenceChangeListener { _, _ ->
@@ -42,6 +46,7 @@ class OtherSettingsFragment : AbsSettingsFragment() {
val preference: Preference? = findPreference("last_added_interval")
preference?.setOnPreferenceChangeListener { lastAdded, newValue ->
setSummary(lastAdded, newValue)
+ libraryViewModel.forceReload(HomeSections)
true
}
val languagePreference: Preference? = findPreference("language_name")
diff --git a/app/src/main/java/code/name/monkey/retromusic/fragments/songs/SongsFragment.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/songs/SongsFragment.kt
index 3db01eb75..533aa0f75 100644
--- a/app/src/main/java/code/name/monkey/retromusic/fragments/songs/SongsFragment.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/fragments/songs/SongsFragment.kt
@@ -1,7 +1,7 @@
package code.name.monkey.retromusic.fragments.songs
import android.os.Bundle
-import android.view.View
+import android.view.*
import androidx.annotation.LayoutRes
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.GridLayoutManager
@@ -9,20 +9,17 @@ import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.adapter.song.SongAdapter
import code.name.monkey.retromusic.fragments.ReloadType
import code.name.monkey.retromusic.fragments.base.AbsRecyclerViewCustomGridSizeFragment
-import code.name.monkey.retromusic.interfaces.MainActivityFragmentCallbacks
+import code.name.monkey.retromusic.helper.SortOrder.SongSortOrder
import code.name.monkey.retromusic.util.PreferenceUtil
+import code.name.monkey.retromusic.util.RetroUtil
-class SongsFragment :
- AbsRecyclerViewCustomGridSizeFragment(),
- MainActivityFragmentCallbacks {
- override fun handleBackPress(): Boolean {
- return false
- }
+class SongsFragment : AbsRecyclerViewCustomGridSizeFragment() {
+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- libraryViewModel.songsLiveData.observe(viewLifecycleOwner, Observer {
+ libraryViewModel.getSongs().observe(viewLifecycleOwner, Observer {
if (it.isNotEmpty())
adapter?.swapDataSet(it)
else
@@ -42,7 +39,7 @@ class SongsFragment :
return SongAdapter(
requireActivity(),
dataSet,
- R.layout.item_list,
+ itemLayoutRes(),
null
)
}
@@ -88,6 +85,213 @@ class SongsFragment :
libraryViewModel.forceReload(ReloadType.Songs)
}
+ override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
+ val gridSizeItem: MenuItem = menu.findItem(R.id.action_grid_size)
+ if (RetroUtil.isLandscape()) {
+ gridSizeItem.setTitle(R.string.action_grid_size_land)
+ }
+ setUpGridSizeMenu(gridSizeItem.subMenu)
+ val layoutItem = menu.findItem(R.id.action_layout_type)
+ setupLayoutMenu(layoutItem.subMenu)
+ setUpSortOrderMenu(menu.findItem(R.id.action_sort_order).subMenu)
+ super.onCreateOptionsMenu(menu, inflater)
+ }
+
+ private fun setUpSortOrderMenu(
+ sortOrderMenu: SubMenu
+ ) {
+ val currentSortOrder: String? = getSortOrder()
+ sortOrderMenu.clear()
+ sortOrderMenu.add(
+ 0,
+ R.id.action_song_sort_order_asc,
+ 0,
+ R.string.sort_order_a_z
+ ).isChecked =
+ currentSortOrder == SongSortOrder.SONG_A_Z
+ sortOrderMenu.add(
+ 0,
+ R.id.action_song_sort_order_desc,
+ 1,
+ R.string.sort_order_z_a
+ ).isChecked =
+ currentSortOrder == SongSortOrder.SONG_Z_A
+ sortOrderMenu.add(
+ 0,
+ R.id.action_song_sort_order_artist,
+ 2,
+ R.string.sort_order_artist
+ ).isChecked =
+ currentSortOrder == SongSortOrder.SONG_ARTIST
+ sortOrderMenu.add(
+ 0,
+ R.id.action_song_sort_order_album,
+ 3,
+ R.string.sort_order_album
+ ).isChecked =
+ currentSortOrder == SongSortOrder.SONG_ALBUM
+ sortOrderMenu.add(
+ 0,
+ R.id.action_song_sort_order_year,
+ 4,
+ R.string.sort_order_year
+ ).isChecked =
+ currentSortOrder == SongSortOrder.SONG_YEAR
+ sortOrderMenu.add(
+ 0,
+ R.id.action_song_sort_order_date,
+ 5,
+ R.string.sort_order_date
+ ).isChecked =
+ currentSortOrder == SongSortOrder.SONG_DATE
+ sortOrderMenu.add(
+ 0,
+ R.id.action_song_sort_order_date_modified,
+ 6,
+ R.string.sort_order_date_modified
+ ).isChecked =
+ currentSortOrder == SongSortOrder.SONG_DATE_MODIFIED
+ sortOrderMenu.add(
+ 0,
+ R.id.action_song_sort_order_composer,
+ 7,
+ R.string.sort_order_composer
+ ).isChecked =
+ currentSortOrder == SongSortOrder.COMPOSER
+
+ sortOrderMenu.setGroupCheckable(0, true, true)
+ }
+
+ private fun setupLayoutMenu(
+ subMenu: SubMenu
+ ) {
+ when (itemLayoutRes()) {
+ R.layout.item_card -> subMenu.findItem(R.id.action_layout_card).isChecked = true
+ R.layout.item_grid -> subMenu.findItem(R.id.action_layout_normal).isChecked = true
+ R.layout.item_card_color ->
+ subMenu.findItem(R.id.action_layout_colored_card).isChecked = true
+ R.layout.item_grid_circle ->
+ subMenu.findItem(R.id.action_layout_circular).isChecked = true
+ R.layout.image -> subMenu.findItem(R.id.action_layout_image).isChecked = true
+ R.layout.item_image_gradient ->
+ subMenu.findItem(R.id.action_layout_gradient_image).isChecked = true
+ }
+ }
+
+ private fun setUpGridSizeMenu(
+ gridSizeMenu: SubMenu
+ ) {
+ when (getGridSize()) {
+ 1 -> gridSizeMenu.findItem(R.id.action_grid_size_1).isChecked =
+ true
+ 2 -> gridSizeMenu.findItem(R.id.action_grid_size_2).isChecked = true
+ 3 -> gridSizeMenu.findItem(R.id.action_grid_size_3).isChecked = true
+ 4 -> gridSizeMenu.findItem(R.id.action_grid_size_4).isChecked = true
+ 5 -> gridSizeMenu.findItem(R.id.action_grid_size_5).isChecked = true
+ 6 -> gridSizeMenu.findItem(R.id.action_grid_size_6).isChecked = true
+ 7 -> gridSizeMenu.findItem(R.id.action_grid_size_7).isChecked = true
+ 8 -> gridSizeMenu.findItem(R.id.action_grid_size_8).isChecked = true
+ }
+ val gridSize: Int = maxGridSize
+ if (gridSize < 8) {
+ gridSizeMenu.findItem(R.id.action_grid_size_8).isVisible = false
+ }
+ if (gridSize < 7) {
+ gridSizeMenu.findItem(R.id.action_grid_size_7).isVisible = false
+ }
+ if (gridSize < 6) {
+ gridSizeMenu.findItem(R.id.action_grid_size_6).isVisible = false
+ }
+ if (gridSize < 5) {
+ gridSizeMenu.findItem(R.id.action_grid_size_5).isVisible = false
+ }
+ if (gridSize < 4) {
+ gridSizeMenu.findItem(R.id.action_grid_size_4).isVisible = false
+ }
+ if (gridSize < 3) {
+ gridSizeMenu.findItem(R.id.action_grid_size_3).isVisible = false
+ }
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ if (handleGridSizeMenuItem(item)) {
+ return true
+ }
+ if (handleLayoutResType(item)) {
+ return true
+ }
+ if (handleSortOrderMenuItem(item)) {
+ return true
+ }
+ return super.onOptionsItemSelected(item)
+ }
+
+ private fun handleSortOrderMenuItem(
+ item: MenuItem
+ ): Boolean {
+ var sortOrder: String? = null
+
+ when (item.itemId) {
+ R.id.action_song_sort_order_asc -> sortOrder = SongSortOrder.SONG_A_Z
+ R.id.action_song_sort_order_desc -> sortOrder = SongSortOrder.SONG_Z_A
+ R.id.action_song_sort_order_artist -> sortOrder = SongSortOrder.SONG_ARTIST
+ R.id.action_song_sort_order_album -> sortOrder = SongSortOrder.SONG_ALBUM
+ R.id.action_song_sort_order_year -> sortOrder = SongSortOrder.SONG_YEAR
+ R.id.action_song_sort_order_date -> sortOrder = SongSortOrder.SONG_DATE
+ R.id.action_song_sort_order_composer -> sortOrder = SongSortOrder.COMPOSER
+ R.id.action_song_sort_order_date_modified -> sortOrder =
+ SongSortOrder.SONG_DATE_MODIFIED
+ }
+ if (sortOrder != null) {
+ item.isChecked = true
+ setAndSaveSortOrder(sortOrder)
+ return true
+ }
+ return false
+ }
+
+ private fun handleLayoutResType(
+ item: MenuItem
+ ): Boolean {
+ var layoutRes = -1
+ when (item.itemId) {
+ R.id.action_layout_normal -> layoutRes = R.layout.item_grid
+ R.id.action_layout_card -> layoutRes = R.layout.item_card
+ R.id.action_layout_colored_card -> layoutRes = R.layout.item_card_color
+ R.id.action_layout_circular -> layoutRes = R.layout.item_grid_circle
+ R.id.action_layout_image -> layoutRes = R.layout.image
+ R.id.action_layout_gradient_image -> layoutRes = R.layout.item_image_gradient
+ }
+ if (layoutRes != -1) {
+ item.isChecked = true
+ setAndSaveLayoutRes(layoutRes)
+ return true
+ }
+ return false
+ }
+
+ private fun handleGridSizeMenuItem(
+ item: MenuItem
+ ): Boolean {
+ var gridSize = 0
+ when (item.itemId) {
+ R.id.action_grid_size_1 -> gridSize = 1
+ R.id.action_grid_size_2 -> gridSize = 2
+ R.id.action_grid_size_3 -> gridSize = 3
+ R.id.action_grid_size_4 -> gridSize = 4
+ R.id.action_grid_size_5 -> gridSize = 5
+ R.id.action_grid_size_6 -> gridSize = 6
+ R.id.action_grid_size_7 -> gridSize = 7
+ R.id.action_grid_size_8 -> gridSize = 8
+ }
+ if (gridSize > 0) {
+ item.isChecked = true
+ setAndSaveGridSize(gridSize)
+ return true
+ }
+ return false
+ }
+
companion object {
@JvmField
var TAG: String = SongsFragment::class.java.simpleName
diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/AlbumGlideRequest.java b/app/src/main/java/code/name/monkey/retromusic/glide/AlbumGlideRequest.java
index fab61c615..82e65da20 100644
--- a/app/src/main/java/code/name/monkey/retromusic/glide/AlbumGlideRequest.java
+++ b/app/src/main/java/code/name/monkey/retromusic/glide/AlbumGlideRequest.java
@@ -69,7 +69,7 @@ public class AlbumGlideRequest {
}
@NonNull
- public Builder checkIgnoreMediaStore(@NonNull Context context) {
+ public Builder checkIgnoreMediaStore() {
return ignoreMediaStore(PreferenceUtil.INSTANCE.isIgnoreMediaStoreArtwork());
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/SingleColorTarget.kt b/app/src/main/java/code/name/monkey/retromusic/glide/SingleColorTarget.kt
new file mode 100644
index 000000000..d4b2db1cc
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/glide/SingleColorTarget.kt
@@ -0,0 +1,39 @@
+package code.name.monkey.retromusic.glide
+
+import android.graphics.drawable.Drawable
+import android.widget.ImageView
+import code.name.monkey.appthemehelper.util.ATHUtil
+import code.name.monkey.retromusic.R
+import code.name.monkey.retromusic.glide.palette.BitmapPaletteTarget
+import code.name.monkey.retromusic.glide.palette.BitmapPaletteWrapper
+import code.name.monkey.retromusic.util.ColorUtil
+import com.bumptech.glide.request.animation.GlideAnimation
+
+
+abstract class SingleColorTarget(view: ImageView) : BitmapPaletteTarget(view) {
+
+ protected val defaultFooterColor: Int
+ get() = ATHUtil.resolveColor(view.context, R.attr.colorControlNormal)
+
+ abstract fun onColorReady(color: Int)
+
+ override fun onLoadFailed(e: Exception?, errorDrawable: Drawable?) {
+ super.onLoadFailed(e, errorDrawable)
+ onColorReady(defaultFooterColor)
+ }
+
+ override fun onResourceReady(
+ resource: BitmapPaletteWrapper?,
+ glideAnimation: GlideAnimation?
+ ) {
+ super.onResourceReady(resource, glideAnimation)
+ resource?.let {
+ onColorReady(
+ ColorUtil.getColor(
+ it.palette,
+ ATHUtil.resolveColor(view.context, R.attr.colorPrimary)
+ )
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt b/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt
index a6f709427..43d23120d 100644
--- a/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/glide/artistimage/ArtistImageLoader.kt
@@ -15,8 +15,8 @@
package code.name.monkey.retromusic.glide.artistimage
import android.content.Context
-import code.name.monkey.retromusic.deezer.DeezerApiService
-import code.name.monkey.retromusic.deezer.Data
+import code.name.monkey.retromusic.model.Data
+import code.name.monkey.retromusic.network.DeezerService
import code.name.monkey.retromusic.util.MusicUtil
import code.name.monkey.retromusic.util.PreferenceUtil
import com.bumptech.glide.Priority
@@ -38,7 +38,7 @@ class ArtistImage(val artistName: String)
class ArtistImageFetcher(
private val context: Context,
- private val deezerApiService: DeezerApiService,
+ private val deezerService: DeezerService,
val model: ArtistImage,
val urlLoader: ModelLoader,
val width: Int,
@@ -66,16 +66,16 @@ class ArtistImageFetcher(
PreferenceUtil.isAllowedToDownloadMetadata()
) {
val artists = model.artistName.split(",")
- val response = deezerApiService.getArtistImage(artists[0]).execute()
+ val response = deezerService.getArtistImage(artists[0]).execute()
if (!response.isSuccessful) {
- throw IOException("Request failed with code: " + response.code());
+ throw IOException("Request failed with code: " + response.code())
}
if (isCancelled) return null
return try {
- val deezerResponse = response.body();
+ val deezerResponse = response.body()
val imageUrl = deezerResponse?.data?.get(0)?.let { getHighestQuality(it) }
// Fragile way to detect a place holder image returned from Deezer:
// ex: "https://e-cdns-images.dzcdn.net/images/artist//250x250-000000-80-0-0.jpg"
@@ -106,7 +106,7 @@ class ArtistImageFetcher(
class ArtistImageLoader(
val context: Context,
- private val deezerApiService: DeezerApiService,
+ private val deezerService: DeezerService,
private val urlLoader: ModelLoader
) : StreamModelLoader {
@@ -115,7 +115,7 @@ class ArtistImageLoader(
width: Int,
height: Int
): DataFetcher