//We give the item and the index since the public "YoutubePlaylists" array is not updated yet. private void YoutubeItemSynced(PlaylistItem item, int syncedPlaylistIndex) { /*The display order is * - Local Header * - Local Playlists * - Youtube Header * - Synced Playlists * Since local header and local playlists are both contained in the "LocalPlaylists" array, to get the position of the syncedPlaylist, * we need to sum the LocalPlaylists count (this sum get the position of the youtube header) and then we add the syncedPlaylistIndex.*/ PlaylistHolder holder = (PlaylistHolder)ListView.FindViewHolderForAdapterPosition(LocalPlaylists.Count + syncedPlaylistIndex); if (holder != null) { holder.Owner.Text = item.Owner; Picasso.With(Application.Context).Load(item.ImageURL).Placeholder(Resource.Color.background_material_dark).Resize(400, 400).CenterCrop().Into(holder.AlbumArt); if (item.HasWritePermission) { holder.edit.Visibility = ViewStates.Visible; } holder.sync.SetImageResource(Resource.Drawable.Sync); holder.sync.Visibility = ViewStates.Visible; holder.SyncLoading.Visibility = ViewStates.Gone; } }
private YtFile GetYtFileFromSearchResult(SearchResult result) { switch (result.Id.Kind) { case "youtube#video": Song videoInfo = new Song(System.Net.WebUtility.HtmlDecode(result.Snippet.Title), result.Snippet.ChannelTitle, result.Snippet.Thumbnails.High.Url, result.Id.VideoId, -1, -1, null, true, false) { ChannelID = result.Snippet.ChannelId }; if (result.Snippet.LiveBroadcastContent == "live") { videoInfo.IsLiveStream = true; } return(new YtFile(videoInfo, YtKind.Video)); case "youtube#playlist": PlaylistItem playlistInfo = new PlaylistItem(result.Snippet.Title, -1, result.Id.PlaylistId) { HasWritePermission = false, ImageURL = result.Snippet.Thumbnails.High.Url, Owner = result.Snippet.ChannelTitle }; return(new YtFile(playlistInfo, YtKind.Playlist)); case "youtube#channel": Channel channelInfo = new Channel(result.Snippet.Title, result.Id.ChannelId, result.Snippet.Thumbnails.High.Url); return(new YtFile(channelInfo, YtKind.Channel)); default: Console.WriteLine("&Kind = " + result.Id.Kind); return(null); } }
public async void PlaylistMore(PlaylistItem item) { BottomSheetDialog bottomSheet = new BottomSheetDialog(MainActivity.instance); View bottomView = MainActivity.instance.LayoutInflater.Inflate(Resource.Layout.BottomSheet, null); bottomView.FindViewById <TextView>(Resource.Id.bsTitle).Text = item.Name; bottomView.FindViewById <TextView>(Resource.Id.bsArtist).Text = item.Owner; Picasso.With(MainActivity.instance).Load(item.ImageURL).Placeholder(Resource.Color.background_material_dark).Transform(new RemoveBlackBorder(true)).Into(bottomView.FindViewById <ImageView>(Resource.Id.bsArt)); bottomSheet.SetContentView(bottomView); List <BottomSheetAction> actions = new List <BottomSheetAction> { new BottomSheetAction(Resource.Drawable.Play, MainActivity.instance.Resources.GetString(Resource.String.play_in_order), (sender, eventArg) => { PlaylistManager.PlayInOrder(item); bottomSheet.Dismiss(); }), new BottomSheetAction(Resource.Drawable.Shuffle, MainActivity.instance.Resources.GetString(Resource.String.random_play), (sender, eventArg) => { PlaylistManager.Shuffle(item); bottomSheet.Dismiss(); }), new BottomSheetAction(Resource.Drawable.Queue, MainActivity.instance.Resources.GetString(Resource.String.add_to_queue), (sender, eventArg) => { PlaylistManager.AddToQueue(item); bottomSheet.Dismiss(); }), new BottomSheetAction(Resource.Drawable.Download, MainActivity.instance.Resources.GetString(Resource.String.download), (sender, eventArg) => { YoutubeManager.DownloadPlaylist(item, true, false); bottomSheet.Dismiss(); }) }; if (await PlaylistManager.IsForked(item)) { actions.Add(new BottomSheetAction(Resource.Drawable.Delete, MainActivity.instance.Resources.GetString(Resource.String.unfork), (sender, eventArg) => { PlaylistManager.Unfork(item); bottomSheet.Dismiss(); })); } else { actions.Add(new BottomSheetAction(Resource.Drawable.LibraryAdd, MainActivity.instance.Resources.GetString(Resource.String.add_to_library), (sender, eventArg) => { PlaylistManager.ForkPlaylist(item); bottomSheet.Dismiss(); })); } bottomSheet.FindViewById <ListView>(Resource.Id.bsItems).Adapter = new BottomSheetAdapter(MainActivity.instance, Resource.Layout.BottomSheetText, actions); bottomSheet.Show(); }
private void ListView_ItemLongClick(object sender, int position) { if (result[position].Kind == YtKind.Video) { Song item = result[position].song; MainActivity.instance.More(item); } else if (result[position].Kind == YtKind.Playlist) { PlaylistItem item = result[position].playlist; PlaylistMore(item); } }
async void LoadMulitplePlaylists(int slot, IList <string> playlistIDs) { List <PlaylistItem> playlists = new List <PlaylistItem>(); foreach (string playlistID in playlistIDs) { PlaylistItem playlist = await PlaylistManager.GetPlaylist(playlistID); if (playlist != null) { playlists.Add(playlist); } } sections[slot] = new Section(sections[slot].SectionTitle, SectionType.PlaylistList, playlists); adapter.NotifyItemChanged(slot); }
public static Fragment NewInstance(PlaylistItem item) { instance = new PlaylistTracks { Arguments = new Bundle() }; instance.item = item; instance.useHeader = true; instance.isInEditMode = item.HasWritePermission && item.LocalID != 0; instance.fullyLoadded = item.LocalID != 0 && item.LocalID != -1; Task.Run(async() => { instance.isForked = await PlaylistManager.IsForked(item); }); return(instance); }
/// <summary> /// Download a playlist or update the local playlist with new songs. /// </summary> /// <param name="playlist">The playlist you want to download.</param> /// <param name="keepPlaylistSynced">True if you want to add the playlist in the keep synced database (warning, this wont add the playlist to the saved ones) </param> /// <param name="showToast">True if you want this method to display that the download has started</param> public static async void DownloadPlaylist(PlaylistItem playlist, bool keepPlaylistSynced, bool showToast) { if (!await MainActivity.instance.WaitForYoutube()) { return; } if (!await MainActivity.instance.GetReadPermission()) { return; } if (!await MainActivity.instance.GetWritePermission()) { return; } if (showToast) { Toast.MakeText(Android.App.Application.Context, Resource.String.syncing, ToastLength.Short).Show(); } long LocalID = playlist.LocalID != 0 ? playlist.LocalID : await PlaylistManager.GetPlaylistID(playlist.Name); if (LocalID == -1) { ContentValues value = new ContentValues(); value.Put(Playlists.InterfaceConsts.Name, playlist.Name); MainActivity.instance.ContentResolver.Insert(Playlists.ExternalContentUri, value); LocalID = await PlaylistManager.GetPlaylistID(playlist.Name); } playlist.LocalID = LocalID; Playlist.instance?.StartSyncing(playlist.Name); if (keepPlaylistSynced) { await Task.Run(() => { SQLiteConnection db = new SQLiteConnection(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "SyncedPlaylists.sqlite")); db.CreateTable <PlaylistItem>(); db.InsertOrReplace(playlist); }); } List <string> names = new List <string>(); List <string> videoIDs = new List <string>(); string nextPageToken = ""; while (nextPageToken != null) { var ytPlaylistRequest = YoutubeService.PlaylistItems.List("snippet, contentDetails"); ytPlaylistRequest.PlaylistId = playlist.YoutubeID; ytPlaylistRequest.MaxResults = 50; ytPlaylistRequest.PageToken = nextPageToken; var ytPlaylist = await ytPlaylistRequest.ExecuteAsync(); foreach (var item in ytPlaylist.Items) { names.Add(item.Snippet.Title); videoIDs.Add(item.ContentDetails.VideoId); } nextPageToken = ytPlaylist.NextPageToken; } if (names.Count > 0) { await Downloader.Init(); List <DownloadFile> files = new List <DownloadFile>(); for (int i = 0; i < names.Count; i++) { if (videoIDs[i] != null && videoIDs[i] != "") { files.Add(new DownloadFile(names[i], videoIDs[i], playlist.Name)); } } ISharedPreferences prefManager = PreferenceManager.GetDefaultSharedPreferences(Android.App.Application.Context); Downloader.instance.DownloadPlaylist(files, LocalID, prefManager.GetBoolean("keepDeleted", true)); } }
public async Task PopulateView() { if (!populating) { populating = true; //Initialisation LocalPlaylists.Clear(); YoutubePlaylists.Clear(); LocalPlaylists.Add(new PlaylistItem("Header", -1)); YoutubePlaylists.Add(new PlaylistItem("Header", null)); PlaylistItem Loading = new PlaylistItem("Loading", null); //Get all local playlist and display an error message if we have an error. (List <PlaylistItem> locPlaylists, string error) = await PlaylistManager.GetLocalPlaylists(false); if (instance == null) { return; } if (error != null) //an error has occured { LocalPlaylists.Add(new PlaylistItem("Error", -1) { Owner = error }); } //Handle synced playlist from the local playlist array we had before. (List <PlaylistItem> loc, List <PlaylistItem> SyncedPlaylists) = await PlaylistManager.ProcessSyncedPlaylists(locPlaylists); if (instance == null) { return; } if (error == null) { if (loc == null || loc.Count == 0) //Every local playlist is a synced one { LocalPlaylists.Add(new PlaylistItem("EMPTY", -1) { Owner = Resources.GetString(Resource.String.local_playlist_empty) }); } else { LocalPlaylists.AddRange(loc); } } YoutubePlaylists.AddRange(SyncedPlaylists); //Display this for now, we'll load non synced youtube playlist in the background. LoadingView.Visibility = ViewStates.Gone; YoutubePlaylists.Add(Loading); adapter = new PlaylistAdapter(LocalPlaylists, YoutubePlaylists); ListView.SetAdapter(adapter); adapter.ItemClick += ListView_ItemClick; adapter.ItemLongCLick += ListView_ItemLongClick; ListView.SetItemAnimator(new DefaultItemAnimator()); //Youtube saved playlists List <PlaylistItem> yt = await PlaylistManager.GetSavedYoutubePlaylists(YoutubePlaylists, YoutubeItemSynced); if (instance == null) { return; } if (yt != null) { int startPos = YoutubePlaylists.Count - 1; YoutubePlaylists.InsertRange(startPos, yt); adapter.NotifyItemRangeInserted(LocalPlaylists.Count + startPos, yt.Count); } //Youtube owned playlists (yt, error) = await PlaylistManager.GetOwnedYoutubePlaylists(YoutubePlaylists, YoutubeItemSynced); if (instance == null) { return; } if (error != null) { YoutubePlaylists.Remove(Loading); adapter.NotifyItemRemoved(LocalPlaylists.Count + YoutubePlaylists.Count); YoutubePlaylists.Add(new PlaylistItem("Error", null) { Owner = error, HasWritePermission = yt != null }); //I use this to check witch error is called. Not really clean but it'll go. adapter.NotifyItemInserted(LocalPlaylists.Count + YoutubePlaylists.Count); populating = false; SyncError(); adapter.forkSaved = true; return; } else { YoutubePlaylists.Remove(Loading); int loadPos = LocalPlaylists.Count + YoutubePlaylists.Count; YoutubePlaylists.AddRange(yt); adapter.NotifyItemChanged(loadPos); adapter.NotifyItemRangeInserted(loadPos + 1, yt.Count - 1); adapter.forkSaved = true; } if (SyncedPlaylists.Count > 0) { List <PlaylistItem> BadSync = SyncedPlaylists.FindAll(x => x.SyncState == SyncState.Loading); for (int i = 0; i < SyncedPlaylists.Count; i++) { SyncedPlaylists[i].SyncState = SyncState.Error; } LocalPlaylists.AddRange(BadSync); if (BadSync.Count > 0) { if (LocalPlaylists[1].Name == "EMPTY") { LocalPlaylists.RemoveAt(1); adapter.NotifyItemRemoved(1); } adapter.NotifyItemRangeInserted(LocalPlaylists.Count - SyncedPlaylists.Count, BadSync.Count); } } populating = false; } }
public void More(int Position) { bool local = Position <= LocalPlaylists.Count; PlaylistItem item = local ? LocalPlaylists[Position] : YoutubePlaylists[Position - LocalPlaylists.Count]; BottomSheetDialog bottomSheet = new BottomSheetDialog(MainActivity.instance); View bottomView = LayoutInflater.Inflate(Resource.Layout.BottomSheet, null); bottomView.FindViewById <TextView>(Resource.Id.bsTitle).Text = item.Name; if (!local || item.SyncState != SyncState.False) { bottomView.FindViewById <TextView>(Resource.Id.bsArtist).Text = item.Owner; Picasso.With(MainActivity.instance).Load(item.ImageURL).Placeholder(Resource.Color.background_material_dark).Transform(new RemoveBlackBorder(true)).Into(bottomView.FindViewById <ImageView>(Resource.Id.bsArt)); } else { bottomView.FindViewById <TextView>(Resource.Id.bsArtist).Text = item.Count + " element" + (item.Count == 1 ? "" : "s"); bottomView.FindViewById <ImageView>(Resource.Id.bsArt).Visibility = ViewStates.Gone; } bottomSheet.SetContentView(bottomView); if (item.SyncState == SyncState.Error) { bottomSheet.FindViewById <ListView>(Resource.Id.bsItems).Adapter = new BottomSheetAdapter(MainActivity.instance, Resource.Layout.BottomSheetText, new List <BottomSheetAction> { //new BottomSheetAction(Resource.Drawable.SyncDisabled, Resources.GetString(Resource.String.stop_sync), (sender, eventArg) => //{ // PlaylistManager.StopSyncingDialog(item, () => // { // PlaylistItem LocalPlaylist = new PlaylistItem(YoutubePlaylists[Position - LocalPlaylists.Count].Name, item.LocalID, YoutubePlaylists[Position - LocalPlaylists.Count].Count); // LocalPlaylists.Add(LocalPlaylist); // if (LocalPlaylists.Count == 3 && LocalPlaylists[1].Name == "EMPTY") // { // LocalPlaylists.RemoveAt(1); // adapter.NotifyItemChanged(1); // } // else // adapter.NotifyItemInserted(LocalPlaylists.Count); // YoutubePlaylists[Position - LocalPlaylists.Count].LocalID = 0; // YoutubePlaylists[Position - LocalPlaylists.Count].SyncState = SyncState.False; // PlaylistHolder holder = (PlaylistHolder)ListView.GetChildViewHolder(ListView.GetChildAt(Position)); // holder.sync.Visibility = ViewStates.Gone; // holder.SyncLoading.Visibility = ViewStates.Gone; // }); // bottomSheet.Dismiss(); //}), new BottomSheetAction(Resource.Drawable.Delete, Resources.GetString(Resource.String.delete), (sender, eventArg) => { PlaylistManager.Delete(item, () => { if (local) { LocalPlaylists.RemoveAt(Position); adapter.NotifyItemRemoved(Position); if (LocalPlaylists.Count == 1) { LocalPlaylists.Add(new PlaylistItem("EMPTY", -1) { Owner = Resources.GetString(Resource.String.local_playlist_empty) }); adapter.NotifyItemInserted(1); } } else { YoutubePlaylists.RemoveAt(Position - LocalPlaylists.Count); adapter.NotifyItemRemoved(Position); if (YoutubePlaylists.Count == 1) { YoutubePlaylists.Add(new PlaylistItem("EMPTY", null) { Owner = Resources.GetString(Resource.String.youtube_playlist_empty) }); adapter.NotifyItemInserted(LocalPlaylists.Count + YoutubePlaylists.Count); } } }); bottomSheet.Dismiss(); }) }); bottomSheet.Show(); return; } List <BottomSheetAction> actions = new List <BottomSheetAction> { new BottomSheetAction(Resource.Drawable.Play, Resources.GetString(Resource.String.play_in_order), (sender, eventArg) => { PlaylistManager.PlayInOrder(item); bottomSheet.Dismiss(); }), new BottomSheetAction(Resource.Drawable.Shuffle, Resources.GetString(Resource.String.random_play), (sender, eventArg) => { PlaylistManager.Shuffle(item); bottomSheet.Dismiss(); }), new BottomSheetAction(Resource.Drawable.Queue, Resources.GetString(Resource.String.add_to_queue), (sender, eventArg) => { PlaylistManager.AddToQueue(item); bottomSheet.Dismiss(); }) }; if (local || item.HasWritePermission) { actions.AddRange(new BottomSheetAction[] { new BottomSheetAction(Resource.Drawable.Edit, Resources.GetString(Resource.String.rename), (sender, eventArg) => { PlaylistManager.Rename(item, () => { adapter.NotifyItemChanged(Position); }); bottomSheet.Dismiss(); }), new BottomSheetAction(Resource.Drawable.Delete, Resources.GetString(Resource.String.delete), (sender, eventArg) => { PlaylistManager.Delete(item, () => { if (local) { LocalPlaylists.RemoveAt(Position); adapter.NotifyItemRemoved(Position); if (LocalPlaylists.Count == 1) { LocalPlaylists.Add(new PlaylistItem("EMPTY", -1) { Owner = Resources.GetString(Resource.String.local_playlist_empty) }); adapter.NotifyItemInserted(1); } } else { YoutubePlaylists.RemoveAt(Position - LocalPlaylists.Count); adapter.NotifyItemRemoved(Position); if (YoutubePlaylists.Count == 1) { YoutubePlaylists.Add(new PlaylistItem("EMPTY", null) { Owner = Resources.GetString(Resource.String.youtube_playlist_empty) }); adapter.NotifyItemInserted(LocalPlaylists.Count + YoutubePlaylists.Count); } } }); bottomSheet.Dismiss(); }) }); } if (item.SyncState == SyncState.True) { actions.AddRange(new BottomSheetAction[] { new BottomSheetAction(Resource.Drawable.Sync, Resources.GetString(Resource.String.sync_now), (sender, eventArg) => { YoutubeManager.DownloadPlaylist(item, true, true); bottomSheet.Dismiss(); }), new BottomSheetAction(Resource.Drawable.SyncDisabled, Resources.GetString(Resource.String.stop_sync), (sender, eventArg) => { PlaylistManager.StopSyncingDialog(item, () => { PlaylistItem LocalPlaylist = new PlaylistItem(YoutubePlaylists[Position - LocalPlaylists.Count].Name, item.LocalID, YoutubePlaylists[Position - LocalPlaylists.Count].Count); LocalPlaylists.Add(LocalPlaylist); if (LocalPlaylists.Count == 3 && LocalPlaylists[1].Name == "EMPTY") { LocalPlaylists.RemoveAt(1); adapter.NotifyItemChanged(1); } else { adapter.NotifyItemInserted(LocalPlaylists.Count); } YoutubePlaylists[Position - LocalPlaylists.Count].LocalID = 0; YoutubePlaylists[Position - LocalPlaylists.Count].SyncState = SyncState.False; PlaylistHolder holder = (PlaylistHolder)ListView.GetChildViewHolder(ListView.GetChildAt(Position)); holder.sync.Visibility = ViewStates.Gone; holder.SyncLoading.Visibility = ViewStates.Gone; }); bottomSheet.Dismiss(); }) }); } else if (!local) { actions.Add(new BottomSheetAction(Resource.Drawable.Sync, Resources.GetString(Resource.String.sync), (sender, eventArg) => { YoutubeManager.DownloadPlaylist(item, true, true); bottomSheet.Dismiss(); })); if (!item.HasWritePermission) { actions.Add(new BottomSheetAction(Resource.Drawable.Delete, Resources.GetString(Resource.String.unfork), (sender, eventArg) => { if (item.SyncState == SyncState.Error) { PlaylistManager.StopSyncing(item); } PlaylistManager.Unfork(item); YoutubePlaylists.RemoveAt(Position - LocalPlaylists.Count); adapter.NotifyItemRemoved(Position); bottomSheet.Dismiss(); })); } } bottomSheet.FindViewById <ListView>(Resource.Id.bsItems).Adapter = new BottomSheetAdapter(MainActivity.instance, Resource.Layout.BottomSheetText, actions); bottomSheet.Show(); }
private void ListView_ItemClick(object sender, int Position) { if (Position == LocalPlaylists.Count + YoutubePlaylists.Count) { View view = LayoutInflater.Inflate(Resource.Layout.SaveAPlaylist, null); AlertDialog dialog = new AlertDialog.Builder(Activity, MainActivity.dialogTheme) .SetTitle(Resource.String.add_playlist_msg) .SetView(view) .SetNegativeButton(Resource.String.cancel, (s, eventArgs) => { }) .SetPositiveButton(Resource.String.add, async(s, eventArgs) => { if (YoutubeExplode.YoutubeClient.TryParsePlaylistId(view.FindViewById <EditText>(Resource.Id.playlistURL).Text, out string playlistID)) { PlaylistItem addPlaylist = await PlaylistManager.GetPlaylist(playlistID); PlaylistManager.ForkPlaylist(addPlaylist); if (YoutubePlaylists[YoutubePlaylists.Count - 1].Name == "EMPTY" || YoutubePlaylists[YoutubePlaylists.Count - 1].Name == "Error") { if (YoutubePlaylists[YoutubePlaylists.Count - 1].Name == "EMPTY") { YoutubePlaylists.Insert(YoutubePlaylists.Count - 2, addPlaylist); YoutubePlaylists.RemoveAt(2); adapter.NotifyItemChanged(LocalPlaylists.Count + YoutubePlaylists.Count - 2); } else { YoutubePlaylists.Insert(YoutubePlaylists.Count - 1, addPlaylist); adapter.NotifyItemInserted(LocalPlaylists.Count + YoutubePlaylists.Count - 2); } } else { YoutubePlaylists.Add(addPlaylist); adapter.NotifyItemInserted(LocalPlaylists.Count + YoutubePlaylists.Count - 1); } } else { Snackbar snackBar = Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), MainActivity.instance.GetString(Resource.String.badplaylisturl), Snackbar.LengthLong); snackBar.View.FindViewById <TextView>(Resource.Id.snackbar_text).SetTextColor(Color.White); snackBar.Show(); } }) .Show(); return; } bool local = Position <= LocalPlaylists.Count; PlaylistItem playlist = local ? LocalPlaylists[Position] : YoutubePlaylists[Position - LocalPlaylists.Count]; if (playlist.SyncState == SyncState.Error && local) { //Handle sync errors } instance = null; MainActivity.instance.contentRefresh.Refresh -= OnRefresh; MainActivity.instance.contentRefresh.Refresh -= OnRefresh; MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(playlist)).AddToBackStack("Playlist Track").Commit(); }
public Section(string sectionTitle, SectionType contentType, List <Song> contentValue, PlaylistItem playlist) { SectionTitle = sectionTitle; this.contentType = contentType; this.contentValue = contentValue; this.playlist = playlist; }
public static Song ToSong(PlaylistItem item) { return(new Song(item.Name, item.Owner, item.ImageURL, item.YoutubeID, -1, item.LocalID, null, false, item.HasWritePermission)); }