Allow renaming a playlist

This commit is contained in:
Nicolas Pomepuy 2024-02-15 10:12:55 +01:00 committed by Duncan McNamara
parent 1669b693c0
commit 06448f32c1
7 changed files with 53 additions and 2 deletions

View File

@ -27,12 +27,14 @@ import android.view.*
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.paging.PagedList import androidx.paging.PagedList
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.google.android.material.appbar.AppBarLayout import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import kotlinx.coroutines.launch
import org.videolan.medialibrary.interfaces.Medialibrary import org.videolan.medialibrary.interfaces.Medialibrary
import org.videolan.medialibrary.interfaces.media.MediaWrapper import org.videolan.medialibrary.interfaces.media.MediaWrapper
import org.videolan.medialibrary.interfaces.media.Playlist import org.videolan.medialibrary.interfaces.media.Playlist
@ -242,8 +244,22 @@ class PlaylistFragment : BaseAudioBrowser<PlaylistsViewModel>(), SwipeRefreshLay
override fun onCtxAction(position: Int, option: ContextOption) { override fun onCtxAction(position: Int, option: ContextOption) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
if (option == CTX_PLAY_ALL) MediaUtils.playAll(activity, viewModel.provider as MedialibraryProvider<MediaWrapper>, position, false) when (option) {
else super.onCtxAction(position, option) CTX_PLAY_ALL -> MediaUtils.playAll(activity, viewModel.provider as MedialibraryProvider<MediaWrapper>, position, false)
CTX_RENAME -> {
val media = getCurrentAdapter()?.getItem(position) ?: return
val dialog = RenameDialog.newInstance(media)
dialog.show(requireActivity().supportFragmentManager, RenameDialog::class.simpleName)
dialog.setListener { item, name ->
lifecycleScope.launch {
viewModel.rename(media, name)
}
}
}
else -> super.onCtxAction(position, option)
}
} }
override fun onRefresh() { override fun onRefresh() {

View File

@ -85,6 +85,7 @@ enum class ContextOption : Flag {
fun createCtxPlaylistAlbumFlags() = createCtxAudioFlags().apply { fun createCtxPlaylistAlbumFlags() = createCtxAudioFlags().apply {
add(CTX_DELETE) add(CTX_DELETE)
add(CTX_RENAME)
} }
fun createCtxPlaylistItemFlags() = createBaseFlags().apply { fun createCtxPlaylistItemFlags() = createBaseFlags().apply {

View File

@ -23,6 +23,8 @@ package org.videolan.vlc.viewmodels.mobile
import android.content.Context import android.content.Context
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.videolan.medialibrary.interfaces.media.Playlist import org.videolan.medialibrary.interfaces.media.Playlist
import org.videolan.medialibrary.media.MediaLibraryItem import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.vlc.gui.PlaylistFragment import org.videolan.vlc.gui.PlaylistFragment
@ -41,6 +43,11 @@ class PlaylistsViewModel(context: Context, type: Playlist.Type) : MedialibraryVi
providerInCard = settings.getBoolean(displayModeKey, providerInCard) providerInCard = settings.getBoolean(displayModeKey, providerInCard)
} }
suspend fun rename(media: MediaLibraryItem, name: String) {
withContext(Dispatchers.IO) { (media as? Playlist)?.setName(name) }
refresh()
}
class Factory(val context: Context, val type: Playlist.Type): ViewModelProvider.NewInstanceFactory() { class Factory(val context: Context, val type: Playlist.Type): ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T { override fun <T : ViewModel> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")

View File

@ -1736,6 +1736,16 @@ playlistDelete(JNIEnv* env, jobject thiz, jobject medialibrary, jlong playlistId
return aml->PlaylistDelete(playlistId); return aml->PlaylistDelete(playlistId);
} }
jboolean
setPlaylistName(JNIEnv* env, jobject thiz, jobject medialibrary, jlong id, jstring name) {
AndroidMediaLibrary *aml = MediaLibrary_getInstance(env, medialibrary);
const char *char_name = env->GetStringUTFChars(name, JNI_FALSE);
const medialibrary::PlaylistPtr playlist = aml->playlist(id);
const bool result = playlist->setName(char_name);
env->ReleaseStringUTFChars(name, char_name);
return result;
}
/* /*
* Folder methods * Folder methods
*/ */
@ -2671,6 +2681,7 @@ static JNINativeMethod playlist_methods[] = {
{"nativePlaylistMove", "(Lorg/videolan/medialibrary/interfaces/Medialibrary;JII)Z", (void*)playlistMove }, {"nativePlaylistMove", "(Lorg/videolan/medialibrary/interfaces/Medialibrary;JII)Z", (void*)playlistMove },
{"nativePlaylistRemove", "(Lorg/videolan/medialibrary/interfaces/Medialibrary;JI)Z", (void*)playlistRemove }, {"nativePlaylistRemove", "(Lorg/videolan/medialibrary/interfaces/Medialibrary;JI)Z", (void*)playlistRemove },
{"nativePlaylistDelete", "(Lorg/videolan/medialibrary/interfaces/Medialibrary;J)Z", (void*)playlistDelete }, {"nativePlaylistDelete", "(Lorg/videolan/medialibrary/interfaces/Medialibrary;J)Z", (void*)playlistDelete },
{"nativePlaylistSetName", "(Lorg/videolan/medialibrary/interfaces/Medialibrary;JLjava/lang/String;)Z", (void*)setPlaylistName },
{"nativeSetFavorite", "(Lorg/videolan/medialibrary/interfaces/Medialibrary;JZ)Z", (void*)setPlaylistFavorite }, {"nativeSetFavorite", "(Lorg/videolan/medialibrary/interfaces/Medialibrary;JZ)Z", (void*)setPlaylistFavorite },
}; };

View File

@ -51,6 +51,8 @@ public abstract class Playlist extends MediaLibraryItem {
abstract public boolean move(int oldPosition, int newPosition); abstract public boolean move(int oldPosition, int newPosition);
abstract public boolean remove(int position); abstract public boolean remove(int position);
abstract public boolean delete(); abstract public boolean delete();
abstract public boolean setName(String name);
abstract public MediaWrapper[] searchTracks(String query, int sort, boolean desc, boolean includeMissing, boolean onlyFavorites, int nbItems, int offset); abstract public MediaWrapper[] searchTracks(String query, int sort, boolean desc, boolean includeMissing, boolean onlyFavorites, int nbItems, int offset);
abstract public int searchTracksCount(String query); abstract public int searchTracksCount(String query);

View File

@ -80,6 +80,12 @@ public class PlaylistImpl extends Playlist {
return ml.isInitiated() && nativePlaylistDelete(ml, mId); return ml.isInitiated() && nativePlaylistDelete(ml, mId);
} }
@Override
public boolean setName(String name) {
final Medialibrary ml = Medialibrary.getInstance();
return ml.isInitiated() && nativePlaylistSetName(ml, mId, name);
}
public MediaWrapper[] searchTracks(String query, int sort, boolean desc, boolean includeMissing, boolean onlyFavorites, int nbItems, int offset) { public MediaWrapper[] searchTracks(String query, int sort, boolean desc, boolean includeMissing, boolean onlyFavorites, int nbItems, int offset) {
final Medialibrary ml = Medialibrary.getInstance(); final Medialibrary ml = Medialibrary.getInstance();
return ml.isInitiated() ? nativeSearch(ml, mId, query, sort, desc, includeMissing, onlyFavorites, nbItems, offset) : Medialibrary.EMPTY_COLLECTION; return ml.isInitiated() ? nativeSearch(ml, mId, query, sort, desc, includeMissing, onlyFavorites, nbItems, offset) : Medialibrary.EMPTY_COLLECTION;
@ -113,5 +119,7 @@ public class PlaylistImpl extends Playlist {
private native boolean nativePlaylistRemove(Medialibrary ml, long id, int position); private native boolean nativePlaylistRemove(Medialibrary ml, long id, int position);
private native boolean nativePlaylistDelete(Medialibrary ml, long id); private native boolean nativePlaylistDelete(Medialibrary ml, long id);
private native boolean nativePlaylistSetName(Medialibrary ml, long mId, String name);
private native boolean nativeSetFavorite(Medialibrary ml, long id, boolean favorite); private native boolean nativeSetFavorite(Medialibrary ml, long id, boolean favorite);
} }

View File

@ -97,6 +97,12 @@ public class StubPlaylist extends Playlist {
return false; return false;
} }
@Override
public boolean setName(String name) {
mTitle = name;
return true;
}
public MediaWrapper[] searchTracks(String query, int sort, boolean desc, boolean includeMissing, boolean onlyFavorites, int nbItems, int offset) { public MediaWrapper[] searchTracks(String query, int sort, boolean desc, boolean includeMissing, boolean onlyFavorites, int nbItems, int offset) {
ArrayList<MediaWrapper> results = new ArrayList<>(); ArrayList<MediaWrapper> results = new ArrayList<>();
for (MediaWrapper media : dt.mAudioMediaWrappers) { for (MediaWrapper media : dt.mAudioMediaWrappers) {