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 c772c320..ff855947 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,6 +3,7 @@ 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.view.View @@ -95,8 +96,8 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis private fun handlePlaybackIntent(intent: Intent) { lifecycleScope.launch(IO) { - val uri = intent.data - val mimeType = intent.type + 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 @@ -113,9 +114,9 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis MusicPlayerRemote.playFromUri(uri) handled = true } else if (MediaStore.Audio.Playlists.CONTENT_TYPE == mimeType) { - val id = parseIdFromIntent(intent, "playlistId", "playlist").toInt() + val id: Int = parseIdFromIntent(intent, "playlistId", "playlist").toInt() if (id >= 0) { - val position = intent.getIntExtra("position", 0) + val position: Int = intent.getIntExtra("position", 0) val songs: List = PlaylistSongsLoader.getPlaylistSongList(this@MainActivity, id) MusicPlayerRemote.openQueue(songs, position, true) @@ -124,7 +125,7 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis } else if (MediaStore.Audio.Albums.CONTENT_TYPE == mimeType) { val id = parseIdFromIntent(intent, "albumId", "album").toInt() if (id >= 0) { - val position = intent.getIntExtra("position", 0) + val position: Int = intent.getIntExtra("position", 0) MusicPlayerRemote.openQueue( libraryViewModel.albumById(id).songs!!, position, @@ -133,9 +134,9 @@ class MainActivity : AbsSlidingMusicPanelActivity(), OnSharedPreferenceChangeLis handled = true } } else if (MediaStore.Audio.Artists.CONTENT_TYPE == mimeType) { - val id = parseIdFromIntent(intent, "artistId", "artist").toInt() + val id: Int = parseIdFromIntent(intent, "artistId", "artist").toInt() if (id >= 0) { - val position = intent.getIntExtra("position", 0) + val position: Int = intent.getIntExtra("position", 0) MusicPlayerRemote.openQueue( libraryViewModel.artistById(id).songs, position, 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 17f0d78d..1d21b803 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 @@ -22,6 +22,7 @@ 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 @@ -33,7 +34,6 @@ 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, @@ -73,7 +73,7 @@ class PlaylistAdapter( } private fun getPlaylistText(playlist: PlaylistWithSongs): String { - return MusicUtil.playlistInfoString(activity, getSongs(playlist)) + return MusicUtil.getPlaylistInfoString(activity, playlist.songs.toSongs()) } override fun onBindViewHolder(holder: ViewHolder, position: Int) { @@ -81,7 +81,7 @@ class PlaylistAdapter( holder.itemView.isActivated = isChecked(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() @@ -91,20 +91,11 @@ class PlaylistAdapter( //PlaylistBitmapLoader(this, holder, playlist).execute() } - private fun getIconRes(playlist: PlaylistWithSongs): 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) - ) - } - + 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 @@ -129,28 +120,17 @@ class PlaylistAdapter( } private fun getSongList(playlists: List): List { - val songs = ArrayList() - /* for (playlist in playlists) { - songs.addAll(playlist.songs) - if (playlist is AbsCustomPlaylist) { - songs.addAll(playlist.songs()) - } else { - songs.addAll(PlaylistSongsLoader.getPlaylistSongList(activity, playlist.id)) - } - }*/ + val songs = mutableListOf() + playlists.forEach { + songs.addAll(it.songs.toSongs()) + } return songs } - private fun getSongs(playlist: PlaylistWithSongs): List { - val songs = ArrayList() - songs.addAll(playlist.songs) - /*if (playlist is AbsSmartPlaylist) { - songs.addAll(playlist.songs()) - } else { - songs.addAll(playlist.getSongs()) - }*/ - return songs - } + private fun getSongs(playlist: PlaylistWithSongs): List = + mutableListOf().apply { + addAll(playlist.songs) + } inner class ViewHolder(itemView: View) : MediaEntryViewHolder(itemView) { init { 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 ff26fb8a..db5158ae 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 @@ -17,17 +17,14 @@ 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.RealRepository 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.android.ext.android.inject import org.koin.androidx.viewmodel.ext.android.sharedViewModel class CreatePlaylistDialog : DialogFragment() { - private val repository by inject() private val libraryViewModel by sharedViewModel() companion object { @@ -57,9 +54,10 @@ class CreatePlaylistDialog : DialogFragment() { val playlistName = playlistView.text.toString() if (!TextUtils.isEmpty(playlistName)) { lifecycleScope.launch(Dispatchers.IO) { - if (repository.checkPlaylistExists(playlistName).isEmpty()) { - val playlistId = repository.createPlaylist(PlaylistEntity(playlistName)) - repository.insertSongs(songs.map { it.toSongEntity(playlistId.toInt()) }) + 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) diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/ImportPlaylist.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/ImportPlaylist.kt deleted file mode 100644 index 9f46e917..00000000 --- a/app/src/main/java/code/name/monkey/retromusic/dialogs/ImportPlaylist.kt +++ /dev/null @@ -1,7 +0,0 @@ -package code.name.monkey.retromusic.dialogs - -import androidx.fragment.app.DialogFragment - -class ImportPlaylist : DialogFragment() { - -} \ No newline at end of file diff --git a/app/src/main/java/code/name/monkey/retromusic/dialogs/ImportPlaylistFragment.kt b/app/src/main/java/code/name/monkey/retromusic/dialogs/ImportPlaylistFragment.kt new file mode 100644 index 00000000..91452bff --- /dev/null +++ b/app/src/main/java/code/name/monkey/retromusic/dialogs/ImportPlaylistFragment.kt @@ -0,0 +1,111 @@ +package code.name.monkey.retromusic.dialogs + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Toast +import androidx.fragment.app.FragmentActivity +import androidx.lifecycle.Observer +import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import code.name.monkey.retromusic.R +import code.name.monkey.retromusic.adapter.base.MediaEntryViewHolder +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 code.name.monkey.retromusic.util.MusicUtil +import kotlinx.coroutines.Dispatchers.IO +import kotlinx.coroutines.launch + +class ImportPlaylistFragment : + AbsRecyclerViewFragment(), 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() + } + } + } + } +} + +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/fragments/LibraryViewModel.kt b/app/src/main/java/code/name/monkey/retromusic/fragments/LibraryViewModel.kt index 3392ccb8..cdee7637 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 @@ -24,6 +24,7 @@ class LibraryViewModel( private val songs = MutableLiveData>() private val artists = MutableLiveData>() private val playlists = MutableLiveData>() + private val legacyPlaylists = MutableLiveData>() private val genres = MutableLiveData>() private val home = MutableLiveData>() @@ -58,6 +59,11 @@ class LibraryViewModel( return playlists } + fun getLegacyPlaylist(): LiveData> { + fetchLegacyPlaylist() + return legacyPlaylists + } + fun getGenre(): LiveData> { fetchGenres() return genres @@ -92,6 +98,12 @@ class LibraryViewModel( } } + private fun fetchLegacyPlaylist() { + viewModelScope.launch(IO) { + legacyPlaylists.postValue(repository.fetchLegacyPlaylist()) + } + } + private fun fetchGenres() { viewModelScope.launch(IO) { genres.postValue(repository.fetchGenres()) @@ -186,6 +198,12 @@ class LibraryViewModel( 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) + } enum class ReloadType { 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 ef41cdf3..f49876f3 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 @@ -61,7 +61,8 @@ class LibraryFragment : AbsMainActivityFragment(R.layout.fragment_library) { null, navOptions ) - R.id.action_add_to_playlist -> CreatePlaylistDialog().show( + R.id.action_import_playlist -> findNavController(R.id.fragment_container).navigate(R.id.action_import_playlist) + R.id.action_add_to_playlist -> CreatePlaylistDialog.create(emptyList()).show( childFragmentManager, "ShowCreatePlaylistDialog" ) 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 8d9b639e..95f849a2 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 @@ -6,14 +6,14 @@ 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 kotlinx.android.synthetic.main.fragment_library.* -class PlaylistsFragment : AbsRecyclerViewFragment() { +class PlaylistsFragment : AbsRecyclerViewFragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -28,8 +28,8 @@ class PlaylistsFragment : AbsRecyclerViewFragment suspend fun fetchArtists(): List suspend fun albumArtists(): List - suspend fun allPlaylists(): List + suspend fun fetchLegacyPlaylist(): List suspend fun fetchGenres(): List suspend fun search(query: String?): MutableList suspend fun getPlaylistSongs(playlist: Playlist): List @@ -125,7 +125,7 @@ class RealRepository( override suspend fun topAlbums(): List = topPlayedRepository.topAlbums() - override suspend fun allPlaylists(): List = playlistRepository.playlists() + override suspend fun fetchLegacyPlaylist(): List = playlistRepository.playlists() override suspend fun fetchGenres(): List = genreRepository.genres() diff --git a/app/src/main/res/layout/item_list.xml b/app/src/main/res/layout/item_list.xml index 30a61347..fac82e1e 100755 --- a/app/src/main/res/layout/item_list.xml +++ b/app/src/main/res/layout/item_list.xml @@ -89,6 +89,7 @@ android:layout_height="wrap_content" android:ellipsize="end" android:maxLines="1" + android:textAppearance="@style/TextViewBody2" android:textColor="?android:attr/textColorSecondary" tools:text="@tools:sample/full_names" /> diff --git a/app/src/main/res/layout/item_list_no_image.xml b/app/src/main/res/layout/item_list_no_image.xml index 4e28bbf8..456468b2 100644 --- a/app/src/main/res/layout/item_list_no_image.xml +++ b/app/src/main/res/layout/item_list_no_image.xml @@ -40,6 +40,7 @@ android:layout_height="wrap_content" android:singleLine="true" android:textAppearance="@style/TextViewBody2" + android:textColor="?android:textColorSecondary" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/title" diff --git a/app/src/main/res/navigation/library_graph.xml b/app/src/main/res/navigation/library_graph.xml index d95d705c..e6c85b8f 100644 --- a/app/src/main/res/navigation/library_graph.xml +++ b/app/src/main/res/navigation/library_graph.xml @@ -44,6 +44,11 @@ android:id="@+id/action_home" android:name="code.name.monkey.retromusic.fragments.home.HomeFragment" android:label="" - tools:layout="@layout/fragment_banner_home"/> + tools:layout="@layout/fragment_banner_home" /> + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e69401b9..88412e41 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -884,4 +884,5 @@ Hello blank fragment Done Ok + Import playlist