Browse Source

Medialibrary: implement the playlist type

merge-requests/1614/head
Nicolas Pomepuy 4 years ago
parent
commit
c3c08957a6
  1. 3
      application/television/src/main/java/org/videolan/television/viewmodel/MainTvModel.kt
  2. 3
      application/television/src/main/java/org/videolan/television/viewmodel/MediaBrowserViewModel.kt
  3. 3
      application/vlc-android/src/org/videolan/vlc/gui/PlaylistFragment.kt
  4. 4
      application/vlc-android/src/org/videolan/vlc/gui/dialogs/SavePlaylistDialog.kt
  5. 3
      application/vlc-android/src/org/videolan/vlc/media/MediaSessionBrowser.kt
  6. 6
      application/vlc-android/src/org/videolan/vlc/providers/medialibrary/PlaylistsProvider.kt
  7. 11
      application/vlc-android/src/org/videolan/vlc/viewmodels/mobile/PlaylistsViewModel.kt
  8. 4
      medialibrary/jni/AndroidMediaLibrary.cpp
  9. 2
      medialibrary/jni/AndroidMediaLibrary.h
  10. 16
      medialibrary/jni/medialibrary.cpp
  11. 16
      medialibrary/src/org/videolan/medialibrary/MedialibraryImpl.java
  12. 6
      medialibrary/src/org/videolan/medialibrary/interfaces/Medialibrary.java
  13. 6
      medialibrary/src/org/videolan/medialibrary/stubs/StubMedialibrary.java

3
application/television/src/main/java/org/videolan/television/viewmodel/MainTvModel.kt

@ -33,6 +33,7 @@ import kotlinx.coroutines.channels.actor
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.videolan.medialibrary.interfaces.Medialibrary
import org.videolan.medialibrary.interfaces.media.Playlist
import org.videolan.medialibrary.interfaces.media.MediaWrapper
import org.videolan.medialibrary.media.DummyItem
import org.videolan.medialibrary.media.MediaLibraryItem
@ -202,7 +203,7 @@ class MainTvModel(app: Application) : AndroidViewModel(app), Medialibrary.OnMedi
private fun updatePlaylists() = viewModelScope.launch {
context.getFromMl {
getPagedPlaylists(Medialibrary.SORT_INSERTIONDATE, true, true, NUM_ITEMS_PREVIEW, 0)
getPagedPlaylists(Playlist.Type.All, Medialibrary.SORT_INSERTIONDATE, true, true, NUM_ITEMS_PREVIEW, 0)
}.let {
(playlist as MutableLiveData).value = mutableListOf<MediaLibraryItem>().apply {
add(DummyItem(HEADER_PLAYLISTS, context.getString(R.string.playlists), ""))

3
application/television/src/main/java/org/videolan/television/viewmodel/MediaBrowserViewModel.kt

@ -4,6 +4,7 @@ import android.content.Context
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import org.videolan.medialibrary.interfaces.media.Playlist
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.resources.*
import org.videolan.vlc.providers.medialibrary.*
@ -22,7 +23,7 @@ class MediaBrowserViewModel(context: Context, val category: Long, val parent : M
CATEGORY_ARTISTS -> ArtistsProvider(context, this, false)
CATEGORY_GENRES -> GenresProvider(context, this)
CATEGORY_VIDEOS -> VideosProvider(null, null, context, this)
CATEGORY_PLAYLISTS -> PlaylistsProvider(context, this)
CATEGORY_PLAYLISTS -> PlaylistsProvider(context, this, Playlist.Type.All)
else -> TracksProvider(null, context, this)
}
override val providers = arrayOf(provider)

3
application/vlc-android/src/org/videolan/vlc/gui/PlaylistFragment.kt

@ -35,6 +35,7 @@ import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton
import org.videolan.medialibrary.interfaces.Medialibrary
import org.videolan.medialibrary.interfaces.media.MediaWrapper
import org.videolan.medialibrary.interfaces.media.Playlist
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.resources.CTX_PLAY_ALL
import org.videolan.tools.Settings
@ -68,7 +69,7 @@ class PlaylistFragment : BaseAudioBrowser<PlaylistsViewModel>(), SwipeRefreshLay
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = getViewModel()
viewModel = getViewModel(Playlist.Type.All)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {

4
application/vlc-android/src/org/videolan/vlc/gui/dialogs/SavePlaylistDialog.kt

@ -153,7 +153,7 @@ class SavePlaylistDialog : VLCBottomSheetDialogFragment(), View.OnClickListener,
}
binding.list.layoutManager = LinearLayoutManager(view.context)
binding.list.adapter = adapter
adapter.submitList(listOf<MediaLibraryItem>(*medialibrary.playlists.apply { forEach { it.description = resources.getQuantityString(R.plurals.media_quantity, it.tracksCount, it.tracksCount) } }))
adapter.submitList(listOf<MediaLibraryItem>(*medialibrary.getPlaylists(Playlist.Type.All).apply { forEach { it.description = resources.getQuantityString(R.plurals.media_quantity, it.tracksCount, it.tracksCount) } }))
if (!Tools.isArrayEmpty(newTracks)) binding.dialogPlaylistSave.setText(R.string.save)
updateEmptyView()
parentFragmentManager.setFragmentResultListener(
@ -261,4 +261,4 @@ class SavePlaylistDialog : VLCBottomSheetDialogFragment(), View.OnClickListener,
}
}
fun Medialibrary.getPlaylistByName(name: String) = playlists.firstOrNull { it.title == name }
fun Medialibrary.getPlaylistByName(name: String) = getPlaylists(Playlist.Type.All).firstOrNull { it.title == name }

3
application/vlc-android/src/org/videolan/vlc/media/MediaSessionBrowser.kt

@ -37,6 +37,7 @@ import androidx.core.net.toUri
import org.videolan.medialibrary.interfaces.Medialibrary
import org.videolan.medialibrary.interfaces.media.Album
import org.videolan.medialibrary.interfaces.media.MediaWrapper
import org.videolan.medialibrary.interfaces.media.Playlist
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.resources.*
import org.videolan.tools.*
@ -293,7 +294,7 @@ class MediaSessionBrowser {
list = genres.copyOfRange(pageOffset.coerceAtMost(genres.size), (pageOffset + MAX_RESULT_SIZE).coerceAtMost(genres.size))
}
ID_PLAYLIST -> {
list = ml.playlists
list = ml.getPlaylists(Playlist.Type.AudioOnly)
list.sortWith(MediaComparators.ANDROID_AUTO)
}
ID_STREAM -> {

6
application/vlc-android/src/org/videolan/vlc/providers/medialibrary/PlaylistsProvider.kt

@ -27,12 +27,12 @@ import org.videolan.medialibrary.interfaces.media.Playlist
import org.videolan.tools.Settings
import org.videolan.vlc.viewmodels.SortableModel
class PlaylistsProvider(context: Context, model: SortableModel) : MedialibraryProvider<Playlist>(context, model) {
class PlaylistsProvider(context: Context, model: SortableModel, val type: Playlist.Type) : MedialibraryProvider<Playlist>(context, model) {
override fun getAll() : Array<Playlist> = medialibrary.getPlaylists(sort, desc, Settings.includeMissing)
override fun getAll() : Array<Playlist> = medialibrary.getPlaylists(type, sort, desc, Settings.includeMissing)
override fun getPage(loadSize: Int, startposition: Int) : Array<Playlist> {
val list = if (model.filterQuery == null) medialibrary.getPagedPlaylists(sort, desc, Settings.includeMissing, loadSize, startposition)
val list = if (model.filterQuery == null) medialibrary.getPagedPlaylists(type, sort, desc, Settings.includeMissing, loadSize, startposition)
else medialibrary.searchPlaylist(model.filterQuery, Playlist.Type.All, sort, desc, Settings.includeMissing, loadSize, startposition)
model.viewModelScope.launch { completeHeaders(list, startposition) }
return list

11
application/vlc-android/src/org/videolan/vlc/viewmodels/mobile/PlaylistsViewModel.kt

@ -23,15 +23,16 @@ package org.videolan.vlc.viewmodels.mobile
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import org.videolan.medialibrary.interfaces.media.Playlist
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.vlc.gui.PlaylistFragment
import org.videolan.vlc.providers.medialibrary.MedialibraryProvider
import org.videolan.vlc.providers.medialibrary.PlaylistsProvider
import org.videolan.vlc.viewmodels.MedialibraryViewModel
class PlaylistsViewModel(context: Context) : MedialibraryViewModel(context) {
class PlaylistsViewModel(context: Context, type: Playlist.Type) : MedialibraryViewModel(context) {
val displayModeKey: String = "display_mode_playlists"
val provider = PlaylistsProvider(context, this)
val provider = PlaylistsProvider(context, this, type)
var providerInCard = true
override val providers : Array<MedialibraryProvider<out MediaLibraryItem>> = arrayOf(provider)
@ -40,12 +41,12 @@ class PlaylistsViewModel(context: Context) : MedialibraryViewModel(context) {
providerInCard = settings.getBoolean(displayModeKey, providerInCard)
}
class Factory(val context: Context): ViewModelProvider.NewInstanceFactory() {
class Factory(val context: Context, val type: Playlist.Type): ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return PlaylistsViewModel(context.applicationContext) as T
return PlaylistsViewModel(context.applicationContext, type) as T
}
}
}
internal fun PlaylistFragment.getViewModel() = ViewModelProvider(requireActivity(), PlaylistsViewModel.Factory(requireContext())).get(PlaylistsViewModel::class.java)
internal fun PlaylistFragment.getViewModel(type: Playlist.Type) = ViewModelProvider(requireActivity(), PlaylistsViewModel.Factory(requireContext(), type)).get(PlaylistsViewModel::class.java)

4
medialibrary/jni/AndroidMediaLibrary.cpp

@ -437,9 +437,9 @@ AndroidMediaLibrary::genre(int64_t genreId)
}
medialibrary::Query<medialibrary::IPlaylist>
AndroidMediaLibrary::playlists(const medialibrary::QueryParameters* params)
AndroidMediaLibrary::playlists(medialibrary::PlaylistType type, medialibrary::QueryParameters* params)
{
return p_ml->playlists(medialibrary::PlaylistType::All, params);
return p_ml->playlists(type, params);
}
medialibrary::PlaylistPtr

2
medialibrary/jni/AndroidMediaLibrary.h

@ -96,7 +96,7 @@ public:
medialibrary::ArtistPtr artist(int64_t artistId);
medialibrary::Query<medialibrary::IGenre> genres(const medialibrary::QueryParameters* params);
medialibrary::GenrePtr genre(int64_t genreId);
medialibrary::Query<medialibrary::IPlaylist> playlists(const medialibrary::QueryParameters* params);
medialibrary::Query<medialibrary::IPlaylist> playlists(medialibrary::PlaylistType type, medialibrary::QueryParameters* params);
medialibrary::PlaylistPtr playlist( int64_t playlistId );
medialibrary::PlaylistPtr PlaylistCreate( const std::string &name );
medialibrary::Query<medialibrary::IMedia> tracksFromAlbum( int64_t albumId, const medialibrary::QueryParameters* params = nullptr );

16
medialibrary/jni/medialibrary.cpp

@ -915,11 +915,11 @@ getGenre(JNIEnv* env, jobject thiz, jlong id)
}
jobjectArray
getPlaylists(JNIEnv* env, jobject thiz, jint sortingCriteria, jboolean desc, jboolean includeMissing)
getPlaylists(JNIEnv* env, jobject thiz, medialibrary::PlaylistType type, jint sortingCriteria, jboolean desc, jboolean includeMissing)
{
AndroidMediaLibrary *aml = MediaLibrary_getInstance(env, thiz);
medialibrary::QueryParameters params = generateParams(sortingCriteria, desc, includeMissing);
std::vector<medialibrary::PlaylistPtr> playlists = aml->playlists(&params)->all();
std::vector<medialibrary::PlaylistPtr> playlists = aml->playlists(type, &params)->all();
jobjectArray playlistRefs = (jobjectArray) env->NewObjectArray(playlists.size(), ml_fields.Playlist.clazz, NULL);
int index = -1;
for(medialibrary::PlaylistPtr const& playlist : playlists) {
@ -931,11 +931,11 @@ getPlaylists(JNIEnv* env, jobject thiz, jint sortingCriteria, jboolean desc, jbo
jobjectArray
getPagedPlaylists(JNIEnv* env, jobject thiz, jint sortingCriteria, jboolean desc, jboolean includeMissing, jint nbItems, jint offset)
getPagedPlaylists(JNIEnv* env, jobject thiz, medialibrary::PlaylistType type, jint sortingCriteria, jboolean desc, jboolean includeMissing, jint nbItems, jint offset)
{
AndroidMediaLibrary *aml = MediaLibrary_getInstance(env, thiz);
medialibrary::QueryParameters params = generateParams(sortingCriteria, desc, includeMissing);
const auto query = aml->playlists(&params);
const auto query = aml->playlists(type, &params);
std::vector<medialibrary::PlaylistPtr> playlists = nbItems != 0 ? query->items(nbItems, offset) : query->all();
jobjectArray playlistRefs = (jobjectArray) env->NewObjectArray(playlists.size(), ml_fields.Playlist.clazz, NULL);
int index = -1;
@ -947,8 +947,8 @@ getPagedPlaylists(JNIEnv* env, jobject thiz, jint sortingCriteria, jboolean desc
}
jint
getPlaylistsCount(JNIEnv* env, jobject thiz) {
return (jint) MediaLibrary_getInstance(env, thiz)->playlists(nullptr)->count();
getPlaylistsCount(JNIEnv* env, medialibrary::PlaylistType type, jobject thiz) {
return (jint) MediaLibrary_getInstance(env, thiz)->playlists(type, nullptr)->count();
}
jobject
@ -2444,8 +2444,8 @@ static JNINativeMethod methods[] = {
{"nativeGetPagedGenres", "(IZZII)[Lorg/videolan/medialibrary/interfaces/media/Genre;", (void*)getPagedGenres },
{"nativeGetGenresCount", "()I", (void*)getGenresCount },
{"nativeGetGenre", "(J)Lorg/videolan/medialibrary/interfaces/media/Genre;", (void*)getGenre },
{"nativeGetPlaylists", "(IZZ)[Lorg/videolan/medialibrary/interfaces/media/Playlist;", (void*)getPlaylists },
{"nativeGetPagedPlaylists", "(IZZII)[Lorg/videolan/medialibrary/interfaces/media/Playlist;", (void*)getPagedPlaylists },
{"nativeGetPlaylists", "(IIZZ)[Lorg/videolan/medialibrary/interfaces/media/Playlist;", (void*)getPlaylists },
{"nativeGetPagedPlaylists", "(IIZZII)[Lorg/videolan/medialibrary/interfaces/media/Playlist;", (void*)getPagedPlaylists },
{"nativeGetPlaylistsCount", "()I", (void*)getPlaylistsCount },
{"nativeGetPlaylist", "(JZ)Lorg/videolan/medialibrary/interfaces/media/Playlist;", (void*)getPlaylist },
{"nativeGetFolders", "(IIZZII)[Lorg/videolan/medialibrary/interfaces/media/Folder;", (void*)folders },

16
medialibrary/src/org/videolan/medialibrary/MedialibraryImpl.java

@ -361,18 +361,18 @@ public class MedialibraryImpl extends Medialibrary {
}
@WorkerThread
public Playlist[] getPlaylists() {
return getPlaylists(Medialibrary.SORT_DEFAULT, false, true);
public Playlist[] getPlaylists(Playlist.Type type) {
return getPlaylists(type, Medialibrary.SORT_DEFAULT, false, true);
}
@WorkerThread
public Playlist[] getPlaylists(int sort, boolean desc, boolean includeMissing) {
return mIsInitiated ? nativeGetPlaylists(sort, desc, includeMissing) : new Playlist[0];
public Playlist[] getPlaylists(Playlist.Type type, int sort, boolean desc, boolean includeMissing) {
return mIsInitiated ? nativeGetPlaylists(type.ordinal(), sort, desc, includeMissing) : new Playlist[0];
}
@WorkerThread
public Playlist[] getPagedPlaylists(int sort, boolean desc, boolean includeMissing, int nbItems, int offset) {
return mIsInitiated ? nativeGetPagedPlaylists(sort, desc, includeMissing, nbItems, offset) : new Playlist[0];
public Playlist[] getPagedPlaylists(Playlist.Type type, int sort, boolean desc, boolean includeMissing, int nbItems, int offset) {
return mIsInitiated ? nativeGetPagedPlaylists(type.ordinal(), sort, desc, includeMissing, nbItems, offset) : new Playlist[0];
}
public int getPlaylistsCount() {
@ -706,8 +706,8 @@ public class MedialibraryImpl extends Medialibrary {
private native Genre[] nativeGetPagedGenres(int sort, boolean desc, boolean includeMissing, int nbItems, int offset);
private native int nativeGetGenresCount();
private native Genre nativeGetGenre(long genreId);
private native Playlist[] nativeGetPlaylists(int sort, boolean desc, boolean includeMissing);
private native Playlist[] nativeGetPagedPlaylists(int sort, boolean desc, boolean includeMissing, int nbItems, int offset);
private native Playlist[] nativeGetPlaylists(int type, int sort, boolean desc, boolean includeMissing);
private native Playlist[] nativeGetPagedPlaylists(int type, int sort, boolean desc, boolean includeMissing, int nbItems, int offset);
private native int nativeGetPlaylistsCount();
private native Playlist nativeGetPlaylist(long playlistId, boolean includeMissing);
private native Playlist nativePlaylistCreate(String name, boolean includeMissing);

6
medialibrary/src/org/videolan/medialibrary/interfaces/Medialibrary.java

@ -753,9 +753,9 @@ abstract public class Medialibrary {
abstract public int getGenresCount();
abstract public int getGenresCount(String query);
abstract public Genre getGenre(long genreId);
abstract public Playlist[] getPlaylists(int sort, boolean desc, boolean includeMissing);
abstract public Playlist[] getPlaylists();
abstract public Playlist[] getPagedPlaylists(int sort, boolean desc, boolean includeMissing, int nbItems, int offset);
abstract public Playlist[] getPlaylists(Playlist.Type type, int sort, boolean desc, boolean includeMissing);
abstract public Playlist[] getPlaylists(Playlist.Type type);
abstract public Playlist[] getPagedPlaylists(Playlist.Type type, int sort, boolean desc, boolean includeMissing, int nbItems, int offset);
abstract public int getPlaylistsCount();
abstract public int getPlaylistsCount(String query);
abstract public Playlist getPlaylist(long playlistId, boolean includeMissing);

6
medialibrary/src/org/videolan/medialibrary/stubs/StubMedialibrary.java

@ -319,15 +319,15 @@ public class StubMedialibrary extends Medialibrary {
return null;
}
public Playlist[] getPlaylists() {
public Playlist[] getPlaylists(Playlist.Type type) {
return dt.mPlaylists.toArray(new Playlist[0]);
}
public Playlist[] getPlaylists(int sort, boolean desc, boolean includeMissing) {
public Playlist[] getPlaylists(Playlist.Type type, int sort, boolean desc, boolean includeMissing) {
return dt.sortPlaylist(dt.mPlaylists, sort, desc);
}
public Playlist[] getPagedPlaylists(int sort, boolean desc, boolean includeMissing, int nbItems, int offset) {
public Playlist[] getPagedPlaylists(Playlist.Type type, int sort, boolean desc, boolean includeMissing, int nbItems, int offset) {
return dt.sortPlaylist(dt.secureSublist(dt.mPlaylists, offset, offset + nbItems), sort, desc);
}

Loading…
Cancel
Save