Skip to content
Snippets Groups Projects
Commit a016652d authored by Geoffrey Métais's avatar Geoffrey Métais
Browse files

Add a Playlists section

Fix #186
parent 1b680520
No related branches found
No related tags found
No related merge requests found
Showing
with 210 additions and 65 deletions
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<include layout="@layout/button_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sliding_tabs"
android:layout_marginTop="@dimen/default_margin"
android:layout_marginLeft="@dimen/default_margin"
android:layout_marginStart="@dimen/default_margin"
android:layout_marginRight="@dimen/default_margin"
android:layout_marginEnd="@dimen/default_margin" />
<org.videolan.vlc.gui.view.SwipeRefreshLayout
android:id="@+id/swipeLayout"
android:layout_width="@dimen/default_content_width"
android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/searchButton"
app:layout_constraintBottom_toBottomOf="parent" >
<include layout="@layout/audio_recyclerview"
android:id="@+id/playlist_list" />
</org.videolan.vlc.gui.view.SwipeRefreshLayout>
<TextView
android:id="@+id/empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/noplaylist"
android:gravity="center"
android:visibility="gone"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
\ No newline at end of file
......@@ -23,6 +23,11 @@
android:title="@string/play_as_audio"
android:icon="@drawable/ic_am_playasaudio_w"
app:showAsAction="always" />
<item
android:id="@+id/action_mode_audio_add_playlist"
android:title="@string/add_to_playlist"
android:icon="@drawable/ic_am_addtoplaylist_w"
app:showAsAction="always"/>
<item
android:id="@+id/action_video_delete"
android:title="@string/delete"
......
......@@ -13,6 +13,10 @@
android:id="@+id/nav_audio"
android:title="@string/audio"
android:icon="@drawable/ic_menu_audio" />
<item
android:id="@+id/nav_playlists"
android:title="@string/playlists"
android:icon="@drawable/ic_menu_audio" />
<item
android:id="@+id/nav_directories"
android:title="@string/directories"
......
/**
* **************************************************************************
* PlaylistFragment.kt
* ****************************************************************************
* Copyright © 2018 VLC authors and VideoLAN
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* ***************************************************************************
*/
package org.videolan.vlc.gui
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.view.ActionMode
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import androidx.paging.PagedList
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import kotlinx.coroutines.launch
import org.videolan.medialibrary.media.MediaLibraryItem
import org.videolan.vlc.R
import org.videolan.vlc.databinding.PlaylistsFragmentBinding
import org.videolan.vlc.gui.audio.AudioBrowserAdapter
import org.videolan.vlc.gui.audio.AudioBrowserFragment
import org.videolan.vlc.gui.audio.BaseAudioBrowser
import org.videolan.vlc.util.AppScope
import org.videolan.vlc.viewmodels.paged.PagedPlaylistsModel
class PlaylistFragment : BaseAudioBrowser(), Observer<PagedList<MediaLibraryItem>>, SwipeRefreshLayout.OnRefreshListener {
private lateinit var binding : PlaylistsFragmentBinding
private lateinit var playlists : RecyclerView
private lateinit var playlistAdapter : AudioBrowserAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (viewModel == null) {
viewModel = ViewModelProviders.of(requireActivity(), PagedPlaylistsModel.Factory(requireContext())).get(PagedPlaylistsModel::class.java)
playlistAdapter = AudioBrowserAdapter(MediaLibraryItem.TYPE_PLAYLIST, this, viewModel.sort)
mAdapter = playlistAdapter
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
binding = PlaylistsFragmentBinding.inflate(inflater, container, false)
playlists = binding.swipeLayout.findViewById(R.id.playlist_list)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.swipeLayout.setOnRefreshListener(this)
playlists.layoutManager = LinearLayoutManager(view.context, RecyclerView.VERTICAL, false)
playlists.adapter = playlistAdapter
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel.pagedList.observe(requireActivity(), this)
viewModel.loading.observe(this, Observer<Boolean> { loading ->
AppScope.launch { binding.swipeLayout.isRefreshing = loading == true }
})
}
override fun onChanged(list: PagedList<MediaLibraryItem>?) {
playlistAdapter.submitList(list)
binding.empty.visibility = if (list.isNullOrEmpty()) View.VISIBLE else View.GONE
}
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
mode.menuInflater.inflate(R.menu.action_mode_audio_browser, menu)
menu.findItem(R.id.action_mode_audio_add_playlist).isVisible = false
return true
}
override fun onClick(v: View, position: Int, item: MediaLibraryItem) {
if (mActionMode == null) {
val i = Intent(activity, PlaylistActivity::class.java)
i.putExtra(AudioBrowserFragment.TAG_ITEM, item)
startActivity(i)
} else super.onClick(v, position, item)
}
override fun onRefresh() {
viewModel.refresh()
}
override fun getTitle() = getString(R.string.playlists)
override fun getCurrentRV() : RecyclerView = playlists
override fun hasFAB() = false
}
\ No newline at end of file
......@@ -21,7 +21,6 @@
package org.videolan.vlc.gui.audio;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
......@@ -38,7 +37,6 @@ import org.videolan.medialibrary.media.MediaLibraryItem;
import org.videolan.medialibrary.media.MediaWrapper;
import org.videolan.vlc.R;
import org.videolan.vlc.gui.PlaylistActivity;
import org.videolan.vlc.gui.SecondaryActivity;
import org.videolan.vlc.gui.view.SwipeRefreshLayout;
import org.videolan.vlc.media.MediaUtils;
import org.videolan.vlc.util.Util;
......@@ -168,12 +166,6 @@ public class AudioAlbumsSongsFragment extends BaseAudioBrowser implements SwipeR
});
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mActivity = (SecondaryActivity) context;
}
@Override
public void onRefresh() {
mActivity.closeSearchView();
......
......@@ -20,7 +20,6 @@
package org.videolan.vlc.gui.audio;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
......@@ -39,8 +38,6 @@ import org.videolan.medialibrary.media.MediaLibraryItem;
import org.videolan.medialibrary.media.MediaWrapper;
import org.videolan.vlc.MediaParsingServiceKt;
import org.videolan.vlc.R;
import org.videolan.vlc.gui.MainActivity;
import org.videolan.vlc.gui.PlaylistActivity;
import org.videolan.vlc.gui.SecondaryActivity;
import org.videolan.vlc.gui.view.SwipeRefreshLayout;
import org.videolan.vlc.media.MediaUtils;
......@@ -51,7 +48,6 @@ import org.videolan.vlc.viewmodels.paged.MLPagedModel;
import org.videolan.vlc.viewmodels.paged.PagedAlbumsModel;
import org.videolan.vlc.viewmodels.paged.PagedArtistsModel;
import org.videolan.vlc.viewmodels.paged.PagedGenresModel;
import org.videolan.vlc.viewmodels.paged.PagedPlaylistsModel;
import org.videolan.vlc.viewmodels.paged.PagedTracksModel;
import java.util.ArrayList;
......@@ -72,13 +68,11 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
private AudioBrowserAdapter mArtistsAdapter;
private AudioBrowserAdapter mAlbumsAdapter;
private AudioBrowserAdapter mGenresAdapter;
private AudioBrowserAdapter mPlaylistAdapter;
private PagedArtistsModel artistModel;
private PagedAlbumsModel albumModel;
private PagedTracksModel tracksModel;
private PagedGenresModel genresModel;
private PagedPlaylistsModel playlistsModel;
private ViewPager mViewPager;
private TabLayout mTabLayout;
......@@ -95,8 +89,7 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
private final static int MODE_ALBUM = 1;
private final static int MODE_SONG = 2;
private final static int MODE_GENRE = 3;
private final static int MODE_PLAYLIST = 4;
private final static int MODE_TOTAL = 5; // Number of audio mProvider modes
private final static int MODE_TOTAL = 4; // Number of audio mProvider modes
public final static String TAG_ITEM = "ML_ITEM";
......@@ -130,7 +123,6 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
getString(R.string.albums),
getString(R.string.tracks),
getString(R.string.genres),
getString(R.string.playlists),
};
mViewPager.setOffscreenPageLimit(MODE_TOTAL - 1);
mViewPager.setAdapter(new AudioPagerAdapter(mLists, titles));
......@@ -180,13 +172,9 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
genresModel = ViewModelProviders.of(requireActivity(), new PagedGenresModel.Factory(requireContext())).get(PagedGenresModel.class);
mGenresAdapter = new AudioBrowserAdapter(MediaLibraryItem.TYPE_GENRE, this, genresModel.getSort());
}
if ((pass != 0 ^ current == MODE_PLAYLIST) && mPlaylistAdapter == null) {
playlistsModel = ViewModelProviders.of(requireActivity(), new PagedPlaylistsModel.Factory(requireContext())).get(PagedPlaylistsModel.class);
mPlaylistAdapter = new AudioBrowserAdapter(MediaLibraryItem.TYPE_PLAYLIST, this, playlistsModel.getSort());
}
}
mAdapters = new AudioBrowserAdapter[] {mArtistsAdapter, mAlbumsAdapter, mSongsAdapter, mGenresAdapter, mPlaylistAdapter};
models = new MLPagedModel[] {artistModel, albumModel, tracksModel, genresModel, playlistsModel};
mAdapters = new AudioBrowserAdapter[] {mArtistsAdapter, mAlbumsAdapter, mSongsAdapter, mGenresAdapter};
models = new MLPagedModel[] {artistModel, albumModel, tracksModel, genresModel};
for (int pass = 0 ; pass < 2; ++pass) {
for (int i = 0; i < models.length; ++i) {
if (pass == 0 ^ current == i) continue;
......@@ -215,12 +203,6 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
mTabLayout.addOnTabSelectedListener(this);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
mActivity = (MainActivity) context;
}
@Override
public void onStart() {
super.onStart();
......@@ -257,7 +239,7 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
super.setFabPlayVisibility(enable && mViewPager.getCurrentItem() == MODE_SONG);
}
public void setFabPlayShuffleAllVisibility() {
private void setFabPlayShuffleAllVisibility() {
setFabPlayVisibility(mViewPager.getCurrentItem() == MODE_SONG && mSongsAdapter.getItemCount() > 2);
}
......@@ -282,9 +264,8 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
return true;
}
private void updateEmptyView(int position) {
private void updateEmptyView() {
mEmptyView.setVisibility(getCurrentAdapter().isEmpty() ? View.VISIBLE : View.GONE);
mEmptyView.setText(position == MODE_PLAYLIST ? R.string.noplaylist : R.string.nomedia);
setFabPlayShuffleAllVisibility();
}
......@@ -297,7 +278,7 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
@Override
public void onPageSelected(int position) {
updateEmptyView(position);
updateEmptyView();
setFabPlayShuffleAllVisibility();
}
......@@ -306,7 +287,7 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
requireActivity().invalidateOptionsMenu();
mSettings.edit().putInt(Constants.KEY_AUDIO_CURRENT_TAB, tab.getPosition()).apply();
final Boolean loading = getViewModel().getLoading().getValue();
if (loading == null || loading == false) mHandler.sendEmptyMessage(UNSET_REFRESHING);
if (loading == null || !loading) mHandler.sendEmptyMessage(UNSET_REFRESHING);
else mHandler.sendEmptyMessage(SET_REFRESHING);
}
......@@ -348,10 +329,6 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
i.putExtra(TAG_ITEM, item);
break;
case MediaLibraryItem.TYPE_ALBUM:
case MediaLibraryItem.TYPE_PLAYLIST:
i = new Intent(getActivity(), PlaylistActivity.class);
i.putExtra(TAG_ITEM, item);
break;
default:
return;
}
......@@ -363,7 +340,7 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
super.onUpdateFinished(adapter);
if (adapter == getCurrentAdapter()) {
mSwipeRefreshLayout.setEnabled(((LinearLayoutManager)getCurrentRV().getLayoutManager()).findFirstVisibleItemPosition() <= 0);
updateEmptyView(mViewPager.getCurrentItem());
updateEmptyView();
}
}
......@@ -398,7 +375,7 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
fragment.mSwipeRefreshLayout.setRefreshing(false);
break;
case UPDATE_EMPTY_VIEW:
fragment.updateEmptyView(fragment.mViewPager.getCurrentItem());
fragment.updateEmptyView();
}
}
}
......@@ -408,10 +385,6 @@ public class AudioBrowserFragment extends BaseAudioBrowser implements SwipeRefre
artistModel.refresh();
}
protected boolean playlistModeSelected() {
return mViewPager.getCurrentItem() == MODE_PLAYLIST;
}
/*
* Disable Swipe Refresh while scrolling horizontally
*/
......
......@@ -23,6 +23,7 @@
package org.videolan.vlc.gui.audio;
import android.content.Context;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
......@@ -67,6 +68,12 @@ public abstract class BaseAudioBrowser extends MediaBrowserFragment<MLPagedModel
abstract protected RecyclerView getCurrentRV();
@Override
public void onAttach(Context context) {
super.onAttach(context);
mActivity = (ContentActivity) context;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
......@@ -81,8 +88,6 @@ public abstract class BaseAudioBrowser extends MediaBrowserFragment<MLPagedModel
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
mode.getMenuInflater().inflate(R.menu.action_mode_audio_browser, menu);
if (playlistModeSelected())
menu.findItem(R.id.action_mode_audio_add_playlist).setVisible(false);
return true;
}
......@@ -159,10 +164,6 @@ public abstract class BaseAudioBrowser extends MediaBrowserFragment<MLPagedModel
@Override
public void onRefresh() {}
protected boolean playlistModeSelected() {
return false;
}
@Override
public void onClick(@NonNull View v, int position, @NonNull MediaLibraryItem item) {
if (mActionMode != null) {
......
......@@ -424,8 +424,8 @@ abstract class BaseBrowserFragment : MediaBrowserFragment<BrowserModel>(), IRefr
val isVideo = mw.type == MediaWrapper.TYPE_VIDEO
val isAudio = mw.type == MediaWrapper.TYPE_AUDIO
val isMedia = isVideo || isAudio
if (isMedia) flags = flags or CTX_PLAY_ALL or CTX_APPEND or CTX_INFORMATION
flags = if (!isAudio) flags or CTX_PLAY_AS_AUDIO else flags or CTX_ADD_TO_PLAYLIST
if (isMedia) flags = flags or CTX_PLAY_ALL or CTX_APPEND or CTX_INFORMATION or CTX_ADD_TO_PLAYLIST
if (!isAudio) flags = flags or CTX_PLAY_AS_AUDIO
if (isVideo) flags = flags or CTX_DOWNLOAD_SUBTITLES
}
if (flags != 0) showContext(requireActivity(), this@BaseBrowserFragment, position, item.getTitle(), flags)
......
......@@ -27,20 +27,12 @@ import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import androidx.transition.TransitionManager;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ActionMode;
import androidx.recyclerview.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.videolan.libvlc.util.AndroidUtil;
import org.videolan.medialibrary.Medialibrary;
import org.videolan.medialibrary.media.MediaLibraryItem;
......@@ -66,6 +58,16 @@ import org.videolan.vlc.viewmodels.SortableModel;
import java.util.LinkedList;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.view.ActionMode;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.RecyclerView;
import androidx.transition.TransitionManager;
public abstract class MediaBrowserFragment<T extends SortableModel> extends Fragment implements androidx.appcompat.view.ActionMode.Callback, Filterable {
public final static String TAG = "VLC/MediaBrowserFragment";
......@@ -93,11 +95,15 @@ public abstract class MediaBrowserFragment<T extends SortableModel> extends Frag
super.onViewCreated(view, savedInstanceState);
mSearchButtonView = view.findViewById(R.id.searchButton);
mSwipeRefreshLayout = view.findViewById(R.id.swipeLayout);
if (mSwipeRefreshLayout != null) mSwipeRefreshLayout.setColorSchemeResources(R.color.orange700);
mFabPlay = getActivity().findViewById(R.id.fab);
mSwipeRefreshLayout.setColorSchemeResources(R.color.orange700);
if (hasFAB()) mFabPlay = requireActivity().findViewById(R.id.fab);
setBreadcrumb();
}
protected boolean hasFAB() {
return mSwipeRefreshLayout != null;
}
protected void setBreadcrumb() {
final RecyclerView ariane = requireActivity().findViewById(R.id.ariane);
if (ariane != null) ariane.setVisibility(View.GONE);
......
......@@ -35,6 +35,7 @@ import org.videolan.vlc.extensions.ExtensionManagerService
import org.videolan.vlc.extensions.api.VLCExtensionItem
import org.videolan.vlc.gui.HistoryFragment
import org.videolan.vlc.gui.MainActivity
import org.videolan.vlc.gui.PlaylistFragment
import org.videolan.vlc.gui.SecondaryActivity
import org.videolan.vlc.gui.audio.AudioBrowserFragment
import org.videolan.vlc.gui.browser.*
......@@ -77,6 +78,7 @@ class Navigator(private val activity: MainActivity,
return when (id) {
R.id.nav_audio -> AudioBrowserFragment()
R.id.nav_directories -> FileBrowserFragment()
R.id.nav_playlists -> PlaylistFragment()
R.id.nav_history -> HistoryFragment()
R.id.nav_network -> NetworkBrowserFragment()
else -> VideoGridFragment()
......@@ -153,6 +155,7 @@ class Navigator(private val activity: MainActivity,
R.id.nav_about -> ID_ABOUT
R.id.nav_settings -> ID_PREFERENCES
R.id.nav_audio -> ID_AUDIO
R.id.nav_playlists -> ID_PLAYLISTS
R.id.nav_directories -> ID_DIRECTORIES
R.id.nav_history -> ID_HISTORY
R.id.nav_mrl -> ID_MRL
......
......@@ -48,6 +48,7 @@ import org.videolan.vlc.gui.SecondaryActivity;
import org.videolan.vlc.gui.browser.MediaBrowserFragment;
import org.videolan.vlc.gui.dialogs.ContextSheetKt;
import org.videolan.vlc.gui.dialogs.CtxActionReceiver;
import org.videolan.vlc.gui.dialogs.SavePlaylistDialog;
import org.videolan.vlc.gui.helpers.UiTools;
import org.videolan.vlc.gui.view.SwipeRefreshLayout;
import org.videolan.vlc.interfaces.IEventsHandler;
......@@ -286,6 +287,9 @@ public class VideoGridFragment extends MediaBrowserFragment<VideosModel> impleme
for (MediaWrapper media : list) media.addFlags(MediaWrapper.MEDIA_FORCE_AUDIO);
MediaUtils.INSTANCE.openList(getActivity(), list, 0);
break;
case R.id.action_mode_audio_add_playlist:
UiTools.addToPlaylist(getActivity(), list);
break;
default:
stopActionMode();
return false;
......@@ -414,6 +418,9 @@ public class VideoGridFragment extends MediaBrowserFragment<VideosModel> impleme
case Constants.CTX_DOWNLOAD_SUBTITLES:
MediaUtils.INSTANCE.getSubs(requireActivity(), media);
break;
case Constants.CTX_ADD_TO_PLAYLIST:
UiTools.addToPlaylist(requireActivity(), media.getTracks(), SavePlaylistDialog.KEY_NEW_TRACKS);
break;
}
}
}
......@@ -31,6 +31,7 @@ const val EXTRA_TARGET = "extra_parse"
//UI Navigation
const val ID_VIDEO = "video"
const val ID_AUDIO = "audio"
const val ID_PLAYLISTS = "playlists"
const val ID_NETWORK = "network"
const val ID_DIRECTORIES = "directories"
const val ID_HISTORY = "history"
......@@ -164,7 +165,7 @@ const val CTX_SUBS_TRACK = 1 shl 21
const val CTX_PICK_SUBS = 1 shl 22
const val CTX_VIDEO_TRACK = 1 shl 23
const val CTX_VIDEO_FLAGS = CTX_APPEND or CTX_DELETE or CTX_DOWNLOAD_SUBTITLES or CTX_INFORMATION or CTX_PLAY_ALL or CTX_PLAY_AS_AUDIO
const val CTX_VIDEO_FLAGS = CTX_APPEND or CTX_DELETE or CTX_DOWNLOAD_SUBTITLES or CTX_INFORMATION or CTX_PLAY_ALL or CTX_PLAY_AS_AUDIO or CTX_ADD_TO_PLAYLIST
const val CTX_TRACK_FLAGS = CTX_APPEND or CTX_PLAY_NEXT or CTX_DELETE or CTX_INFORMATION or CTX_PLAY_ALL or CTX_ADD_TO_PLAYLIST or CTX_SET_RINGTONE
const val CTX_AUDIO_FLAGS = CTX_PLAY or CTX_APPEND or CTX_PLAY_NEXT or CTX_ADD_TO_PLAYLIST
const val CTX_PLAYLIST_FLAGS = CTX_AUDIO_FLAGS or CTX_DELETE
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment