From e376f537015ee3195534396944ea5e462b5b8ff4 Mon Sep 17 00:00:00 2001 From: Anonymus Raccoon <32224410+AnonymusRaccoon@users.noreply.github.com> Date: Tue, 25 Jun 2019 02:02:24 +0200 Subject: [PATCH] Finishing the channel details view, need to finish transition from and to it. --- Opus/Code/Api/ChannelManager.cs | 57 +++ Opus/Code/Api/PlaylistManager.cs | 33 +- Opus/Code/Api/Services/MusicPlayer.cs | 4 +- Opus/Code/Api/SongParser.cs | 16 +- Opus/Code/DataStructure/HomeSection.cs | 9 + Opus/Code/MainActivity.cs | 11 +- Opus/Code/UI/Adapter/HomeListAdapter.cs | 77 ++-- Opus/Code/UI/Adapter/LineAdapter.cs | 2 +- Opus/Code/UI/Adapter/QueueAdapter.cs | 2 +- Opus/Code/UI/Adapter/SectionAdapter.cs | 128 ++++-- Opus/Code/UI/Fragments/ChannelDetails.cs | 176 ++------ Opus/Code/UI/Fragments/PlaylistTracks.cs | 14 +- Opus/Code/UI/Fragments/Queue.cs | 4 +- Opus/Code/UI/Fragments/YoutubeSearch.cs | 2 + Opus/Opus.csproj | 1 + Opus/Resources/Resource.Designer.cs | 514 ++++++++++++----------- Opus/Resources/layout/HomeChannels.xml | 1 + Opus/Resources/layout/HomePlaylists.xml | 2 + Opus/Resources/layout/LineSongs.xml | 2 + Opus/Resources/values-fr/strings.xml | 6 + Opus/Resources/values/strings.xml | 6 + 21 files changed, 568 insertions(+), 499 deletions(-) create mode 100644 Opus/Code/Api/ChannelManager.cs diff --git a/Opus/Code/Api/ChannelManager.cs b/Opus/Code/Api/ChannelManager.cs new file mode 100644 index 0000000..1bc9332 --- /dev/null +++ b/Opus/Code/Api/ChannelManager.cs @@ -0,0 +1,57 @@ +using Google.Apis.YouTube.v3; +using Google.Apis.YouTube.v3.Data; +using Opus.DataStructure; +using System.Collections.Generic; +using System.Threading.Tasks; +using Channel = Opus.DataStructure.Channel; + +namespace Opus.Api +{ + public class ChannelManager + { + /// + /// Return a complete Channel object from the youtube id of the channel + /// + /// + /// + public async static Task GetChannel(string channelID) + { + ChannelsResource.ListRequest request = YoutubeManager.YoutubeService.Channels.List("snippet"); + request.Id = channelID; + + ChannelListResponse response = await request.ExecuteAsync(); + + if (response.Items.Count > 0) + { + var result = response.Items[0]; + return new Channel(result.Snippet.Title, channelID, result.Snippet.Thumbnails.High.Url); + } + else + return null; + } + + /// + /// Return a list of complete Channel objects from the youtube ids of the channels + /// + /// + /// + public async static Task> GetChannels(IEnumerable channelIDs) + { + ChannelsResource.ListRequest request = YoutubeManager.YoutubeService.Channels.List("snippet"); + request.Id = string.Join(";", channelIDs); + + ChannelListResponse response = await request.ExecuteAsync(); + + if (response.Items.Count > 0) + { + List channels = new List(); + foreach (var result in response.Items) + channels.Add(new Channel(result.Snippet.Title, result.Id, result.Snippet.Thumbnails.High.Url)); + + return channels; + } + else + return null; + } + } +} \ No newline at end of file diff --git a/Opus/Code/Api/PlaylistManager.cs b/Opus/Code/Api/PlaylistManager.cs index 55e21b6..2910128 100644 --- a/Opus/Code/Api/PlaylistManager.cs +++ b/Opus/Code/Api/PlaylistManager.cs @@ -39,23 +39,30 @@ namespace Opus.Api /// public static async Task GetPlaylist(string playlistID) { - PlaylistsResource.ListRequest request = YoutubeManager.YoutubeService.Playlists.List("snippet"); - request.Id = playlistID; - - PlaylistListResponse response = await request.ExecuteAsync(); - - if (response.Items.Count > 0) + try { - Playlist result = response.Items[0]; - return new PlaylistItem(result.Snippet.Title, -1, playlistID) + PlaylistsResource.ListRequest request = YoutubeManager.YoutubeService.Playlists.List("snippet"); + request.Id = playlistID; + + PlaylistListResponse response = await request.ExecuteAsync(); + + if (response.Items.Count > 0) { - HasWritePermission = false, - ImageURL = result.Snippet.Thumbnails.High.Url, - Owner = result.Snippet.ChannelTitle - }; + return new PlaylistItem(response.Items[0].Snippet.Title, -1, playlistID) + { + HasWritePermission = false, + ImageURL = response.Items[0].Snippet.Thumbnails.Standard.Url, + Owner = response.Items[0].Snippet.ChannelTitle + }; + } + else + return null; } - else + catch(Exception ex) + { + Console.WriteLine("&Get playlist catch called, ex: " + ex.Message); return null; + } } #region PlayInOrder diff --git a/Opus/Code/Api/Services/MusicPlayer.cs b/Opus/Code/Api/Services/MusicPlayer.cs index 454e0b5..f242262 100644 --- a/Opus/Code/Api/Services/MusicPlayer.cs +++ b/Opus/Code/Api/Services/MusicPlayer.cs @@ -21,7 +21,7 @@ using Com.Google.Android.Exoplayer2.Trackselection; using Com.Google.Android.Exoplayer2.Upstream; using Com.Google.Android.Exoplayer2.Util; using Newtonsoft.Json; -using Opus.Code.Api; +using Opus.Api; using Opus.DataStructure; using Opus.Fragments; using Opus.Others; @@ -974,7 +974,7 @@ namespace Opus.Api.Services } else { - SongParser.playPosition = -1; + SongParser.playPosition = -2; currentID = position; Play(song, StartFromOldPosition ? LastTimer : -1, false); } diff --git a/Opus/Code/Api/SongParser.cs b/Opus/Code/Api/SongParser.cs index 291abf7..9010bef 100644 --- a/Opus/Code/Api/SongParser.cs +++ b/Opus/Code/Api/SongParser.cs @@ -12,7 +12,7 @@ using System.Threading.Tasks; using YoutubeExplode; using YoutubeExplode.Models; -namespace Opus.Code.Api +namespace Opus.Api { public class SongParser { @@ -20,7 +20,7 @@ namespace Opus.Code.Api /// /// The reference of the play item. The song parser will start the playback of this queue item as soon as possible. /// - public static int playPosition = -1; + public static int playPosition = -2; private int queuePosition = -1; private bool canceled = false; @@ -154,7 +154,7 @@ namespace Opus.Code.Api } MusicPlayer.instance.Play(song, -1, queuePosition == -1); - playPosition = -1; + playPosition = -2; } Video video = await client.GetVideoAsync(song.YoutubeID); @@ -187,7 +187,7 @@ namespace Opus.Code.Api if(playPosition == queuePosition) { - playPosition = -1; + playPosition = -2; Queue.instance.RefreshCurrent(); Player.instance?.Ready(); MainActivity.instance.Timout(); @@ -206,7 +206,7 @@ namespace Opus.Code.Api if (playPosition == queuePosition) { - playPosition = -1; + playPosition = -2; Queue.instance.RefreshCurrent(); Player.instance?.Ready(); } @@ -223,7 +223,7 @@ namespace Opus.Code.Api if (playPosition == queuePosition) { - playPosition = -1; + playPosition = -2; Queue.instance.RefreshCurrent(); Player.instance?.Ready(); } @@ -237,7 +237,7 @@ namespace Opus.Code.Api if (playPosition == queuePosition) { - playPosition = -1; + playPosition = -2; Queue.instance.RefreshCurrent(); Player.instance?.Ready(); MainActivity.instance.UnknowError(ErrorCode.SP1, null, Snackbar.LengthLong); @@ -245,7 +245,7 @@ namespace Opus.Code.Api } if (playPosition == queuePosition) - playPosition = -1; + playPosition = -2; queuePosition = -1; instances.Remove(this); return song; diff --git a/Opus/Code/DataStructure/HomeSection.cs b/Opus/Code/DataStructure/HomeSection.cs index 1ee3adb..e64e6d2 100644 --- a/Opus/Code/DataStructure/HomeSection.cs +++ b/Opus/Code/DataStructure/HomeSection.cs @@ -11,6 +11,7 @@ namespace Opus.DataStructure public List contentValue; public List playlistContent; public List channelContent; + public PlaylistItem playlist; public RecyclerView recycler; public Section(string sectionTitle, SectionType contentType) @@ -26,6 +27,14 @@ namespace Opus.DataStructure this.contentValue = contentValue; } + public Section(string sectionTitle, SectionType contentType, List contentValue, PlaylistItem playlist) + { + SectionTitle = sectionTitle; + this.contentType = contentType; + this.contentValue = contentValue; + this.playlist = playlist; + } + public Section(string sectionTitle, SectionType contentType, List playlistContent) { SectionTitle = sectionTitle; diff --git a/Opus/Code/MainActivity.cs b/Opus/Code/MainActivity.cs index 5681ac3..91a43ae 100644 --- a/Opus/Code/MainActivity.cs +++ b/Opus/Code/MainActivity.cs @@ -313,13 +313,12 @@ namespace Opus { if(item.ItemId == Android.Resource.Id.Home) { - if (PlaylistTracks.instance != null || FolderTracks.instance != null) + if (PlaylistTracks.instance != null || FolderTracks.instance != null || ChannelDetails.instance != null) { - Console.WriteLine("&PlaylistTrack back"); - for (int i = 0; i < SupportFragmentManager.BackStackEntryCount; i++) - { - Console.WriteLine("&Back stack entry " + i + ": " + SupportFragmentManager.GetBackStackEntryAt(i)); - } + //for (int i = 0; i < SupportFragmentManager.BackStackEntryCount; i++) + //{ + // Console.WriteLine("&Back stack entry " + i + ": " + SupportFragmentManager.GetBackStackEntryAt(i)); + //} SupportFragmentManager.PopBackStack(); } diff --git a/Opus/Code/UI/Adapter/HomeListAdapter.cs b/Opus/Code/UI/Adapter/HomeListAdapter.cs index 49734ab..25be72e 100644 --- a/Opus/Code/UI/Adapter/HomeListAdapter.cs +++ b/Opus/Code/UI/Adapter/HomeListAdapter.cs @@ -13,59 +13,86 @@ using System.Collections.Generic; namespace Opus.Adapter { - public class HomeListAdapter : RecyclerView.Adapter + public class SmallListAdapter : RecyclerView.Adapter { public RecyclerView recycler; - public int listPadding = 0; - public List channels; + public List channels; public List playlists; - public List allItems; private readonly bool UseChannel; public bool expanded = false; - public override int ItemCount => UseChannel ? (expanded ? (channels.Count > 3 ? 3 : channels.Count) : channels.Count) : - expanded ? (playlists.Count > 3 ? 3 : playlists.Count) : playlists.Count; + public override int ItemCount + { + get + { + if ((UseChannel && channels == null) || (!UseChannel && playlists == null)) + return 1; - public HomeListAdapter(List channels, RecyclerView recycler) + return UseChannel? (expanded? (channels.Count > 3 ? 3 : channels.Count) : channels.Count) : + expanded? (playlists.Count > 3 ? 3 : playlists.Count) : playlists.Count; + } + } + + public SmallListAdapter(List channels, RecyclerView recycler) { this.recycler = recycler; this.channels = channels; UseChannel = true; } - public HomeListAdapter(List playlists, RecyclerView recycler) + public SmallListAdapter(List playlists, RecyclerView recycler) { this.recycler = recycler; this.playlists = playlists; UseChannel = false; } + public SmallListAdapter(bool UseChannel, RecyclerView recycler) + { + this.recycler = recycler; + this.UseChannel = UseChannel; + } + public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { - SongHolder holder = (SongHolder)viewHolder; - - if(UseChannel) + if (position == 0 && ((UseChannel && channels == null) || (!UseChannel && playlists == null))) { - holder.Title.Text = channels[position].Title; - Picasso.With(Application.Context).Load(channels[position].Album).Placeholder(Resource.Color.background_material_dark).Transform(new CircleTransformation()).Into(holder.AlbumArt); - holder.ItemView.SetPadding(4, 1, 4, 1); + EmptyHolder holder = (EmptyHolder)viewHolder; + holder.text.Text = MainActivity.instance.GetString(Resource.String.long_loading); + holder.text.SetHeight(MainActivity.instance.DpToPx(157)); } else { - holder.Title.Text = playlists[position].Name; - Picasso.With(Application.Context).Load(playlists[position].ImageURL).Placeholder(Resource.Color.background_material_dark).Resize(400, 400).CenterCrop().Into(holder.AlbumArt); - if(!holder.RightButtons.FindViewById(Resource.Id.play).HasOnClickListeners) + SongHolder holder = (SongHolder)viewHolder; + + if (UseChannel) { - //Only support local playlists for now. - holder.RightButtons.FindViewById(Resource.Id.play).Click += (sender, e) => { PlaylistManager.PlayInOrder(playlists[position]); }; - holder.RightButtons.FindViewById(Resource.Id.shuffle).Click += (sender, e) => { PlaylistManager.Shuffle(playlists[position]); }; + holder.Title.Text = channels[position].Name; + Picasso.With(Application.Context).Load(channels[position].ImageURL).Placeholder(Resource.Color.background_material_dark).Transform(new CircleTransformation()).Into(holder.AlbumArt); + holder.ItemView.SetPadding(4, 1, 4, 1); + } + else + { + holder.Title.Text = playlists[position].Name; + Picasso.With(Application.Context).Load(playlists[position].ImageURL).Placeholder(Resource.Color.background_material_dark).Resize(400, 400).CenterCrop().Into(holder.AlbumArt); + if (!holder.RightButtons.FindViewById(Resource.Id.play).HasOnClickListeners) + { + //Only support local playlists for now. + holder.RightButtons.FindViewById(Resource.Id.play).Click += (sender, e) => { PlaylistManager.PlayInOrder(playlists[position]); }; + holder.RightButtons.FindViewById(Resource.Id.shuffle).Click += (sender, e) => { PlaylistManager.Shuffle(playlists[position]); }; + } } } } public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType) { - if(UseChannel) + if ((UseChannel && channels == null) || (!UseChannel && playlists == null)) + { + View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.EmptyView, parent, false); + return new EmptyHolder(itemView); + } + else if (UseChannel) { View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.HomeChannel, parent, false); return new SongHolder(itemView, OnClick, OnLongClick); @@ -80,15 +107,9 @@ namespace Opus.Adapter void OnClick(int position) { if(UseChannel) - { - //Open a channel view - } + MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, ChannelDetails.NewInstance(channels[position])).AddToBackStack("Channel Details").Commit(); else - { - MainActivity.instance.contentRefresh.Refresh -= Home.instance.OnRefresh; - Home.instance = null; MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(playlists[position])).AddToBackStack("Playlist Track").Commit(); - } } void OnLongClick(int position) { } diff --git a/Opus/Code/UI/Adapter/LineAdapter.cs b/Opus/Code/UI/Adapter/LineAdapter.cs index c981cf1..c1837ba 100644 --- a/Opus/Code/UI/Adapter/LineAdapter.cs +++ b/Opus/Code/UI/Adapter/LineAdapter.cs @@ -59,7 +59,7 @@ namespace Opus.Adapter if (position == 0 && isEmpty) { EmptyHolder holder = (EmptyHolder)viewHolder; - holder.text.Text = "No song currently in queue,\nstart playing song now !"; + holder.text.Text = UseQueue ? MainActivity.instance.GetString(Resource.String.empty_queue) : MainActivity.instance.GetString(Resource.String.long_loading); holder.text.SetHeight(MainActivity.instance.DpToPx(157)); return; } diff --git a/Opus/Code/UI/Adapter/QueueAdapter.cs b/Opus/Code/UI/Adapter/QueueAdapter.cs index f790499..c5ddfab 100644 --- a/Opus/Code/UI/Adapter/QueueAdapter.cs +++ b/Opus/Code/UI/Adapter/QueueAdapter.cs @@ -7,8 +7,8 @@ using Android.Text; using Android.Text.Style; using Android.Views; using Android.Widget; +using Opus.Api; using Opus.Api.Services; -using Opus.Code.Api; using Opus.DataStructure; using Opus.Others; using Square.Picasso; diff --git a/Opus/Code/UI/Adapter/SectionAdapter.cs b/Opus/Code/UI/Adapter/SectionAdapter.cs index 55579c0..86f3118 100644 --- a/Opus/Code/UI/Adapter/SectionAdapter.cs +++ b/Opus/Code/UI/Adapter/SectionAdapter.cs @@ -70,10 +70,10 @@ namespace Opus.Adapter MainActivity.instance.ShowPlayer(); Player.instance.ShowQueue(); }; - if(MusicPlayer.CurrentID() != -1 && MusicPlayer.CurrentID() <= MusicPlayer.queue.Count) + if (MusicPlayer.CurrentID() != -1 && MusicPlayer.CurrentID() <= MusicPlayer.queue.Count) holder.recycler.ScrollToPosition(MusicPlayer.CurrentID()); } - else if(items[position].SectionTitle == null) + else if (items[position].SectionTitle == null) { //The playlist is loading holder.recycler.SetAdapter(new LineAdapter(new List(), holder.recycler)); @@ -85,65 +85,109 @@ namespace Opus.Adapter holder.more.Click += (sender, e) => { position = holder.AdapterPosition; - //MainActivity.instance.contentRefresh.Refresh -= Home.instance.OnRefresh; - //Home.instance = null; - MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(items[position].contentValue, items[position].SectionTitle)).AddToBackStack(null).Commit(); + if (items[position].playlist == null) + MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(items[position].contentValue, items[position].SectionTitle)).AddToBackStack(null).Commit(); + else + MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(items[position].playlist)).AddToBackStack(null).Commit(); }; } } - else if(items[position].contentType == SectionType.ChannelList) + else if (items[position].contentType == SectionType.ChannelList) { LineSongHolder holder = (LineSongHolder)viewHolder; items[position].recycler = holder.recycler; holder.title.Text = items[position].SectionTitle; holder.recycler.SetLayoutManager(new LinearLayoutManager(MainActivity.instance, LinearLayoutManager.Vertical, false)); - holder.recycler.SetAdapter(new HomeListAdapter(items[position].contentValue.GetRange(0, items[position].contentValue.Count > 4 ? 4 : items[position].contentValue.Count), holder.recycler) { allItems = items[position].contentValue.GetRange(4, items[position].contentValue.Count - 4) }); - ((GradientDrawable)holder.more.Background).SetStroke(5, Android.Content.Res.ColorStateList.ValueOf(Color.Argb(255, 21, 183, 237))); - holder.more.SetTextColor(Color.Argb(255, 21, 183, 237)); - holder.more.Text = ((HomeListAdapter)holder.recycler.GetAdapter()).channels.Count > 4 ? "View Less" : "View More"; - holder.more.Click += (sender, e) => + if(items[position].channelContent != null) { - HomeListAdapter adapter = (HomeListAdapter)holder.recycler.GetAdapter(); - if(adapter.ItemCount == 4) + holder.recycler.SetAdapter(new SmallListAdapter(items[position].channelContent.GetRange(0, items[position].channelContent.Count > 4 ? 4 : items[position].channelContent.Count), holder.recycler)); + + if (items[position].channelContent.Count > 4) { - adapter.channels.AddRange(items[position].contentValue.GetRange(4, items[position].contentValue.Count - 4)); - adapter.NotifyItemRangeInserted(4, items[position].contentValue.Count - 4); - holder.more.Text = "View Less"; + holder.more.Visibility = ViewStates.Visible; + ((GradientDrawable)holder.more.Background).SetStroke(5, Android.Content.Res.ColorStateList.ValueOf(Color.Argb(255, 21, 183, 237))); + holder.more.SetTextColor(Color.Argb(255, 21, 183, 237)); + holder.more.Text = ((SmallListAdapter)holder.recycler.GetAdapter()).channels.Count > 4 ? MainActivity.instance.GetString(Resource.String.view_less) : MainActivity.instance.GetString(Resource.String.view_more); + holder.more.Click += (sender, e) => + { + SmallListAdapter adapter = (SmallListAdapter)holder.recycler.GetAdapter(); + if (adapter.ItemCount == 4) + { + adapter.channels.AddRange(items[position].channelContent.GetRange(4, items[position].channelContent.Count - 4)); + adapter.NotifyItemRangeInserted(4, items[position].channelContent.Count - 4); + holder.more.Text = MainActivity.instance.GetString(Resource.String.view_less); + } + else + { + int count = adapter.channels.Count - 4; + adapter.channels.RemoveRange(4, count); + adapter.NotifyItemRangeRemoved(4, count); + holder.more.Text = MainActivity.instance.GetString(Resource.String.view_more); + } + }; } else - { - int count = adapter.channels.Count - 4; - adapter.channels.RemoveRange(4, count); - adapter.NotifyItemRangeRemoved(4, count); - holder.more.Text = "View More"; - } - }; + holder.more.Visibility = ViewStates.Gone; + } + else + { + holder.recycler.SetAdapter(new SmallListAdapter(false, holder.recycler)); + } + } else if (items[position].contentType == SectionType.PlaylistList) { LineSongHolder holder = (LineSongHolder)viewHolder; + items[position].recycler = holder.recycler; holder.title.Text = items[position].SectionTitle; holder.recycler.SetLayoutManager(new LinearLayoutManager(MainActivity.instance, LinearLayoutManager.Vertical, false)); - holder.recycler.SetAdapter(new HomeListAdapter(items[position].playlistContent.GetRange(0, items[position].playlistContent.Count > 4 ? 4 : items[position].playlistContent.Count), holder.recycler)); - holder.more.Click += (sender, e) => { MainActivity.instance.FindViewById(Resource.Id.bottomView).SelectedItemId = Resource.Id.playlistLayout; }; + if (items[position].playlistContent != null) + { + holder.recycler.SetAdapter(new SmallListAdapter(items[position].playlistContent.GetRange(0, items[position].playlistContent.Count > 4 ? 4 : items[position].playlistContent.Count), holder.recycler)); + + if (ChannelDetails.instance != null) + { + if (items[position].playlistContent.Count > 4) + { + holder.more.Visibility = ViewStates.Visible; + ((GradientDrawable)holder.more.Background).SetStroke(5, Android.Content.Res.ColorStateList.ValueOf(Color.Argb(255, 21, 183, 237))); + holder.more.SetTextColor(Color.Argb(255, 21, 183, 237)); + holder.more.Text = ((SmallListAdapter)holder.recycler.GetAdapter()).playlists.Count > 4 ? MainActivity.instance.GetString(Resource.String.view_less) : MainActivity.instance.GetString(Resource.String.view_more); + holder.more.Click += (sender, e) => + { + SmallListAdapter adapter = (SmallListAdapter)holder.recycler.GetAdapter(); + if (adapter.ItemCount == 4) + { + adapter.playlists.AddRange(items[position].playlistContent.GetRange(4, items[position].playlistContent.Count - 4)); + adapter.NotifyItemRangeInserted(4, items[position].playlistContent.Count - 4); + holder.more.Text = MainActivity.instance.GetString(Resource.String.view_less); + } + else + { + int count = adapter.playlists.Count - 4; + adapter.playlists.RemoveRange(4, count); + adapter.NotifyItemRangeRemoved(4, count); + holder.more.Text = MainActivity.instance.GetString(Resource.String.view_more); + } + }; + } + else + holder.more.Visibility = ViewStates.Gone; + } + else + { + holder.more.Click += (sender, e) => { MainActivity.instance.FindViewById(Resource.Id.bottomView).SelectedItemId = Resource.Id.playlistLayout; }; + holder.more.Visibility = ViewStates.Visible; + } + } + else + { + holder.recycler.SetAdapter(new SmallListAdapter(true, holder.recycler)); + holder.more.Visibility = ViewStates.Gone; + } } - //else if(items[position].contentType == SectionType.TopicSelector) - //{ - // LineSongHolder holder = (LineSongHolder)viewHolder; - // items[position].recycler = holder.recycler; - - // holder.title.Text = items[position].SectionTitle; - // holder.recycler.SetLayoutManager(new LinearLayoutManager(MainActivity.instance, LinearLayoutManager.Vertical, false)); - // holder.recycler.SetAdapter(new HomeListAdapter(items[position].contentValue)); - // holder.more.Click += (sender, e) => - // { - // Intent intent = new Intent(MainActivity.instance, typeof(Preferences)); - // MainActivity.instance.StartActivity(intent); - // }; - - //} } void OnClick(int position) @@ -173,7 +217,11 @@ namespace Opus.Adapter else if (items[position].contentType == SectionType.ChannelList) return 1; else if (items[position].contentType == SectionType.PlaylistList) + { + if (ChannelDetails.instance != null) + return 1; //We want to display the playlists with the same view as the channels for this fragment. return 2; + } else return 4; } diff --git a/Opus/Code/UI/Fragments/ChannelDetails.cs b/Opus/Code/UI/Fragments/ChannelDetails.cs index d4602a0..96ae6fc 100644 --- a/Opus/Code/UI/Fragments/ChannelDetails.cs +++ b/Opus/Code/UI/Fragments/ChannelDetails.cs @@ -1,39 +1,32 @@ -using Android.Content; -using Android.Database; -using Android.Net; -using Android.OS; +using Android.OS; using Android.Support.Design.Widget; using Android.Support.V4.App; using Android.Views; using Android.Widget; -using Java.Lang; using Opus.Adapter; using Opus.Api; using Opus.DataStructure; using Opus.Others; using Square.Picasso; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using YoutubeExplode; -using static Android.Provider.MediaStore.Audio; -using CursorLoader = Android.Support.V4.Content.CursorLoader; using PlaylistItem = Opus.DataStructure.PlaylistItem; -using PopupMenu = Android.Support.V7.Widget.PopupMenu; using RecyclerView = Android.Support.V7.Widget.RecyclerView; using SearchView = Android.Support.V7.Widget.SearchView; using Toolbar = Android.Support.V7.Widget.Toolbar; namespace Opus.Fragments { - public class ChannelDetails : Fragment, /*PopupMenu.IOnMenuItemClickListener,*/ AppBarLayout.IOnOffsetChangedListener + public class ChannelDetails : Fragment, AppBarLayout.IOnOffsetChangedListener { public static ChannelDetails instance; private Channel item; - private TextView EmptyView; private RecyclerView ListView; private SectionAdapter adapter; - private List
sections = new List
(); + private readonly List
sections = new List
(); public override void OnActivityCreated(Bundle savedInstanceState) { @@ -83,7 +76,6 @@ namespace Opus.Fragments public override void OnDestroyView() { - //MainActivity.instance.RemoveFilterListener(Search); if (!MainActivity.instance.Paused) { Activity.FindViewById(Resource.Id.playlistButtons).Visibility = ViewStates.Visible; @@ -92,8 +84,8 @@ namespace Opus.Fragments MainActivity.instance.HideSearch(); MainActivity.instance.SupportActionBar.SetHomeButtonEnabled(false); MainActivity.instance.SupportActionBar.SetDisplayHomeAsUpEnabled(false); - MainActivity.instance.SupportActionBar.SetDisplayShowTitleEnabled(true); MainActivity.instance.SupportActionBar.SetDisplayShowTitleEnabled(false); + MainActivity.instance.FindViewById(Resource.Id.toolbarLogo).Visibility = ViewStates.Visible; MainActivity.instance.contentRefresh.Refresh -= OnRefresh; Activity.FindViewById(Resource.Id.appbar).RemoveOnOffsetChangedListener(this); @@ -139,18 +131,23 @@ namespace Opus.Fragments for (int i = 0; i < response.Items.Count; i++) { - if (response.Items[i].ContentDetails?.Playlists.Count == 1) + if (response.Items[i].ContentDetails?.Playlists?.Count == 1) { - System.Console.WriteLine("&Single playlsit"); sections.Add(new Section(null, SectionType.SinglePlaylist)); LoadPlaylist(sections.Count - 1, response.Items[i].ContentDetails.Playlists[0]); } - //else if (item.ContentDetails.Playlists.Count > 1) - // sections.Add(new Section(item.Snippet.Title, SectionType.PlaylistList, new List())); + else if (response.Items[i].ContentDetails?.Playlists?.Count > 1) + { + sections.Add(new Section(response.Items[i].Snippet.Title, SectionType.PlaylistList)); + LoadMulitplePlaylists(sections.Count - 1, response.Items[i].ContentDetails.Playlists); + } - //else if (item.ContentDetails.Channels.Count > 1) - // sections.Add(new Section(item.Snippet.Title, SectionType.ChannelList, new List())); + else if (response.Items[i].ContentDetails?.Channels?.Count > 1) + { + sections.Add(new Section(response.Items[i].Snippet.Title, SectionType.ChannelList)); + LoadChannels(sections.Count - 1, response.Items[i].ContentDetails.Channels); + } } adapter = new SectionAdapter(sections); @@ -161,9 +158,28 @@ namespace Opus.Fragments async void LoadPlaylist(int slot, string playlistID) { - System.Console.WriteLine("&Loading playlist: " + playlistID + " slot: " + slot + " sections count " + sections.Count); var pl = await new YoutubeClient().GetPlaylistAsync(playlistID, 1); - sections[slot] = new Section(pl.Title, SectionType.SinglePlaylist, Song.FromVideoArray(pl.Videos)); + sections[slot] = new Section(pl.Title, SectionType.SinglePlaylist, Song.FromVideoArray(pl.Videos), new PlaylistItem(pl.Title, -1, playlistID) { HasWritePermission = false, Owner = item.Name }); + adapter.NotifyItemChanged(slot); + } + + async void LoadMulitplePlaylists(int slot, IList playlistIDs) + { + List playlists = new List(); + 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); + } + + async void LoadChannels(int slot, IList channelIDs) + { + IEnumerable channels = await ChannelManager.GetChannels(channelIDs); + sections[slot] = new Section(sections[slot].SectionTitle, SectionType.ChannelList, channels.ToList()); adapter.NotifyItemChanged(slot); } @@ -173,122 +189,10 @@ namespace Opus.Fragments MainActivity.instance.contentRefresh.Refreshing = false; } - //public void Search(object sender, SearchView.QueryTextChangeEventArgs e) - //{ - // if (e.NewText == "") - // query = null; - // else - // query = e.NewText.ToLower(); - - // if (item.LocalID != -1) - // LoaderManager.GetInstance(this).RestartLoader(0, null, this); - // else - // { - // if (query == null) - // adapter.tracks.SetFilter(x => true); - // else - // adapter.tracks.SetFilter(x => x.Title.ToLower().Contains(query) || x.Artist.ToLower().Contains(query)); - - // adapter.NotifyDataSetChanged(); - // } - //} - - public void More(Song song, int position) - { - //BottomSheetDialog bottomSheet = new BottomSheetDialog(MainActivity.instance); - //View bottomView = LayoutInflater.Inflate(Resource.Layout.BottomSheet, null); - //bottomView.FindViewById(Resource.Id.bsTitle).Text = song.Title; - //bottomView.FindViewById(Resource.Id.bsArtist).Text = song.Artist; - //if (song.AlbumArt == -1 || song.IsYt) - //{ - // Picasso.With(MainActivity.instance).Load(song.Album).Placeholder(Resource.Drawable.noAlbum).Transform(new RemoveBlackBorder(true)).Into(bottomView.FindViewById(Resource.Id.bsArt)); - //} - //else - //{ - // var songCover = Uri.Parse("content://media/external/audio/albumart"); - // var songAlbumArtUri = ContentUris.WithAppendedId(songCover, song.AlbumArt); - - // Picasso.With(MainActivity.instance).Load(songAlbumArtUri).Placeholder(Resource.Drawable.noAlbum).Resize(400, 400).CenterCrop().Into(bottomView.FindViewById(Resource.Id.bsArt)); - //} - //bottomSheet.SetContentView(bottomView); - - //List actions = new List - //{ - // new BottomSheetAction(Resource.Drawable.Play, Resources.GetString(Resource.String.play), (sender, eventArg) => - // { - // if(useHeader) - // PlaylistManager.PlayInOrder(item, position); - // else - // SongManager.Play(song); - // bottomSheet.Dismiss(); - // }), - // new BottomSheetAction(Resource.Drawable.PlaylistPlay, Resources.GetString(Resource.String.play_next), (sender, eventArg) => - // { - // SongManager.PlayNext(song); - // bottomSheet.Dismiss(); - // }), - // new BottomSheetAction(Resource.Drawable.Queue, Resources.GetString(Resource.String.play_last), (sender, eventArg) => - // { - // SongManager.PlayLast(song); - // bottomSheet.Dismiss(); - // }), - // new BottomSheetAction(Resource.Drawable.PlaylistAdd, Resources.GetString(Resource.String.add_to_playlist), (sender, eventArg) => - // { - // PlaylistManager.AddSongToPlaylistDialog(song); - // bottomSheet.Dismiss(); - // }) - //}; - - //if (item.HasWritePermission) - //{ - // actions.Add(new BottomSheetAction(Resource.Drawable.Close, Resources.GetString(Resource.String.remove_track_from_playlist), (sender, eventArg) => - // { - // RemoveFromPlaylist(song, position); - // bottomSheet.Dismiss(); - // })); - //} - - //if (!song.IsYt) - //{ - // actions.Add(new BottomSheetAction(Resource.Drawable.Edit, Resources.GetString(Resource.String.edit_metadata), (sender, eventArg) => - // { - // LocalManager.EditMetadata(song); - // bottomSheet.Dismiss(); - // })); - //} - //else - //{ - // actions.AddRange(new BottomSheetAction[] - // { - // new BottomSheetAction(Resource.Drawable.PlayCircle, Resources.GetString(Resource.String.create_mix_from_song), (sender, eventArg) => - // { - // YoutubeManager.CreateMixFromSong(song); - // bottomSheet.Dismiss(); - // }), - // new BottomSheetAction(Resource.Drawable.Download, Resources.GetString(Resource.String.download), (sender, eventArg) => - // { - // YoutubeManager.Download(new[] { song }); - // bottomSheet.Dismiss(); - // }) - // }); - //} - - //bottomSheet.FindViewById(Resource.Id.bsItems).Adapter = new BottomSheetAdapter(MainActivity.instance, Resource.Layout.BottomSheetText, actions); - //bottomSheet.Show(); - } - - public override void OnResume() { base.OnResume(); instance = this; - - //if (!Activity.FindViewById(Resource.Id.headerPlay).HasOnClickListeners) - // Activity.FindViewById(Resource.Id.headerPlay).Click += (sender, e0) => { PlaylistManager.PlayInOrder(item); }; - //if (!Activity.FindViewById(Resource.Id.headerShuffle).HasOnClickListeners) - // Activity.FindViewById(Resource.Id.headerShuffle).Click += (sender, e0) => { PlaylistManager.Shuffle(item); }; - //if (!Activity.FindViewById(Resource.Id.headerMore).HasOnClickListeners) - // Activity.FindViewById(Resource.Id.headerMore).Click += PlaylistMore; } public void OnOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) @@ -307,11 +211,5 @@ namespace Opus.Fragments MainActivity.instance.SupportActionBar.SetDisplayShowTitleEnabled(true); } } - - public override void OnDestroy() - { - base.OnDestroy(); - MainActivity.instance.FindViewById(Resource.Id.toolbarLogo).Visibility = ViewStates.Visible; - } } } diff --git a/Opus/Code/UI/Fragments/PlaylistTracks.cs b/Opus/Code/UI/Fragments/PlaylistTracks.cs index b8e6253..d44f159 100644 --- a/Opus/Code/UI/Fragments/PlaylistTracks.cs +++ b/Opus/Code/UI/Fragments/PlaylistTracks.cs @@ -113,7 +113,8 @@ namespace Opus.Fragments if (item.Count == -1) Activity.FindViewById(Resource.Id.headerNumber).Text = "NaN" + " " + GetString(Resource.String.songs); - Picasso.With(Android.App.Application.Context).Load(item.ImageURL).Placeholder(Resource.Drawable.noAlbum).Transform(new RemoveBlackBorder(true)).Into(Activity.FindViewById(Resource.Id.headerArt)); + if(item.ImageURL != null) + Picasso.With(Android.App.Application.Context).Load(item.ImageURL).Placeholder(Resource.Drawable.noAlbum).Transform(new RemoveBlackBorder(true)).Into(Activity.FindViewById(Resource.Id.headerArt)); } Activity.FindViewById(Resource.Id.collapsingToolbar).RequestLayout(); } @@ -147,8 +148,8 @@ namespace Opus.Fragments MainActivity.instance.HideSearch(); MainActivity.instance.SupportActionBar.SetHomeButtonEnabled(false); MainActivity.instance.SupportActionBar.SetDisplayHomeAsUpEnabled(false); - MainActivity.instance.SupportActionBar.SetDisplayShowTitleEnabled(true); MainActivity.instance.SupportActionBar.SetDisplayShowTitleEnabled(false); + MainActivity.instance.FindViewById(Resource.Id.toolbarLogo).Visibility = ViewStates.Visible; MainActivity.instance.contentRefresh.Refresh -= OnRefresh; Activity.FindViewById(Resource.Id.appbar).RemoveOnOffsetChangedListener(this); @@ -342,6 +343,9 @@ namespace Opus.Fragments tracks.Invalidate(); adapter.NotifyDataSetChanged(); + if(item?.ImageURL == null) + Picasso.With(Android.App.Application.Context).Load(tracks[0].Album).Placeholder(Resource.Drawable.noAlbum).Transform(new RemoveBlackBorder(true)).Into(Activity.FindViewById(Resource.Id.headerArt)); + } catch (System.Net.Http.HttpRequestException) { } } @@ -604,11 +608,5 @@ namespace Opus.Fragments MainActivity.instance.SupportActionBar.SetDisplayShowTitleEnabled(true); } } - - public override void OnDestroy() - { - base.OnDestroy(); - MainActivity.instance.FindViewById(Resource.Id.toolbarLogo).Visibility = ViewStates.Visible; - } } } diff --git a/Opus/Code/UI/Fragments/Queue.cs b/Opus/Code/UI/Fragments/Queue.cs index 25c26ea..a198154 100644 --- a/Opus/Code/UI/Fragments/Queue.cs +++ b/Opus/Code/UI/Fragments/Queue.cs @@ -15,7 +15,6 @@ using Opus; using Opus.Adapter; using Opus.Api; using Opus.Api.Services; -using Opus.Code.Api; using Opus.DataStructure; using Opus.Others; using Opus.Views; @@ -111,7 +110,8 @@ public class Queue : Fragment, RecyclerView.IOnItemTouchListener, PopupMenu.IOnM int last = ((LinearLayoutManager)ListView.GetLayoutManager()).FindLastVisibleItemPosition(); for (int i = first; i <= last; i++) { - if (ListView.GetChildViewHolder(((LinearLayoutManager)ListView.GetLayoutManager()).FindViewByPosition(i)) is SongHolder holder) + View child = ((LinearLayoutManager)ListView.GetLayoutManager()).FindViewByPosition(i); + if (child != null && ListView.GetChildViewHolder(child) is SongHolder holder) { if (MusicPlayer.CurrentID() == i - 1) //The -1 is because the first displayed item of the queue is a header. { diff --git a/Opus/Code/UI/Fragments/YoutubeSearch.cs b/Opus/Code/UI/Fragments/YoutubeSearch.cs index 747ceaf..2c1c655 100644 --- a/Opus/Code/UI/Fragments/YoutubeSearch.cs +++ b/Opus/Code/UI/Fragments/YoutubeSearch.cs @@ -295,6 +295,8 @@ namespace Opus.Fragments Console.WriteLine("&Exception catched in the youtube search: " + ex.Source + " - " + ex.Message); EmptyView.Text = GetString(Resource.String.timout); EmptyView.Visibility = ViewStates.Visible; + EmptyView.Visibility = ViewStates.Visible; + LoadingView.Visibility = ViewStates.Gone; } } diff --git a/Opus/Opus.csproj b/Opus/Opus.csproj index c4b4666..979b396 100644 --- a/Opus/Opus.csproj +++ b/Opus/Opus.csproj @@ -324,6 +324,7 @@ + diff --git a/Opus/Resources/Resource.Designer.cs b/Opus/Resources/Resource.Designer.cs index a2a525c..329e0a9 100644 --- a/Opus/Resources/Resource.Designer.cs +++ b/Opus/Resources/Resource.Designer.cs @@ -7183,14 +7183,14 @@ namespace Opus // aapt resource value: 0x7f0d0072 public const int abc_toolbar_collapse_description = 2131558514; - // aapt resource value: 0x7f0d0135 - public const int add = 2131558709; + // aapt resource value: 0x7f0d0139 + public const int add = 2131558713; - // aapt resource value: 0x7f0d00fb - public const int add_playlist = 2131558651; + // aapt resource value: 0x7f0d00fc + public const int add_playlist = 2131558652; - // aapt resource value: 0x7f0d010f - public const int add_playlist_msg = 2131558671; + // aapt resource value: 0x7f0d0110 + public const int add_playlist_msg = 2131558672; // aapt resource value: 0x7f0d00df public const int add_to_library = 2131558623; @@ -7201,23 +7201,23 @@ namespace Opus // aapt resource value: 0x7f0d00d9 public const int add_to_queue = 2131558617; - // aapt resource value: 0x7f0d011c - public const int album = 2131558684; + // aapt resource value: 0x7f0d0120 + public const int album = 2131558688; - // aapt resource value: 0x7f0d00e9 - public const int all = 2131558633; + // aapt resource value: 0x7f0d00ea + public const int all = 2131558634; // aapt resource value: 0x7f0d0080 public const int appbar_scrolling_view_behavior = 2131558528; - // aapt resource value: 0x7f0d013f - public const int appearances = 2131558719; + // aapt resource value: 0x7f0d0143 + public const int appearances = 2131558723; - // aapt resource value: 0x7f0d0132 - public const int apply = 2131558706; + // aapt resource value: 0x7f0d0136 + public const int apply = 2131558710; - // aapt resource value: 0x7f0d011b - public const int artist = 2131558683; + // aapt resource value: 0x7f0d011f + public const int artist = 2131558687; // aapt resource value: 0x7f0d00ca public const int autoplay = 2131558602; @@ -7225,17 +7225,17 @@ namespace Opus // aapt resource value: 0x7f0d00cb public const int autoplay_desc = 2131558603; - // aapt resource value: 0x7f0d0111 - public const int badplaylisturl = 2131558673; + // aapt resource value: 0x7f0d0112 + public const int badplaylisturl = 2131558674; - // aapt resource value: 0x7f0d0139 - public const int behavior = 2131558713; + // aapt resource value: 0x7f0d013d + public const int behavior = 2131558717; - // aapt resource value: 0x7f0d0159 - public const int beta_available = 2131558745; + // aapt resource value: 0x7f0d015d + public const int beta_available = 2131558749; - // aapt resource value: 0x7f0d0144 - public const int black_theme = 2131558724; + // aapt resource value: 0x7f0d0148 + public const int black_theme = 2131558728; // aapt resource value: 0x7f0d0081 public const int bottom_sheet_behavior = 2131558529; @@ -7243,17 +7243,17 @@ namespace Opus // aapt resource value: 0x7f0d00b2 public const int browse = 2131558578; - // aapt resource value: 0x7f0d0133 - public const int cancel = 2131558707; + // aapt resource value: 0x7f0d0137 + public const int cancel = 2131558711; - // aapt resource value: 0x7f0d015f - public const int cancelling = 2131558751; + // aapt resource value: 0x7f0d0163 + public const int cancelling = 2131558755; - // aapt resource value: 0x7f0d00f1 - public const int cant_delete = 2131558641; + // aapt resource value: 0x7f0d00f2 + public const int cant_delete = 2131558642; - // aapt resource value: 0x7f0d015c - public const int cant_play_non_youtube = 2131558748; + // aapt resource value: 0x7f0d0160 + public const int cant_play_non_youtube = 2131558752; // aapt resource value: 0x7f0d00b7 public const int cast = 2131558583; @@ -7336,11 +7336,11 @@ namespace Opus // aapt resource value: 0x7f0d0015 public const int cast_play = 2131558421; - // aapt resource value: 0x7f0d0130 - public const int cast_queue_push = 2131558704; + // aapt resource value: 0x7f0d0134 + public const int cast_queue_push = 2131558708; - // aapt resource value: 0x7f0d0131 - public const int cast_queue_pushed = 2131558705; + // aapt resource value: 0x7f0d0135 + public const int cast_queue_pushed = 2131558709; // aapt resource value: 0x7f0d0016 public const int cast_rewind = 2131558422; @@ -7390,14 +7390,14 @@ namespace Opus // aapt resource value: 0x7f0d0025 public const int cast_unmute = 2131558437; - // aapt resource value: 0x7f0d011e - public const int change_albumart = 2131558686; + // aapt resource value: 0x7f0d0122 + public const int change_albumart = 2131558690; - // aapt resource value: 0x7f0d0123 - public const int changes_saved = 2131558691; + // aapt resource value: 0x7f0d0127 + public const int changes_saved = 2131558695; - // aapt resource value: 0x7f0d00eb - public const int channels = 2131558635; + // aapt resource value: 0x7f0d00ec + public const int channels = 2131558636; // aapt resource value: 0x7f0d0082 public const int character_counter_content_description = 2131558530; @@ -7405,8 +7405,8 @@ namespace Opus // aapt resource value: 0x7f0d0083 public const int character_counter_pattern = 2131558531; - // aapt resource value: 0x7f0d0146 - public const int check_updates = 2131558726; + // aapt resource value: 0x7f0d014a + public const int check_updates = 2131558730; // aapt resource value: 0x7f0d002b public const int common_google_play_services_enable_button = 2131558443; @@ -7462,14 +7462,14 @@ namespace Opus // aapt resource value: 0x7f0d003b public const int common_signin_button_text_long = 2131558459; - // aapt resource value: 0x7f0d012f - public const int completed = 2131558703; + // aapt resource value: 0x7f0d0133 + public const int completed = 2131558707; - // aapt resource value: 0x7f0d0153 - public const int country_blocked = 2131558739; + // aapt resource value: 0x7f0d0157 + public const int country_blocked = 2131558743; - // aapt resource value: 0x7f0d0117 - public const int create_local = 2131558679; + // aapt resource value: 0x7f0d0118 + public const int create_local = 2131558680; // aapt resource value: 0x7f0d00cc public const int create_mix = 2131558604; @@ -7477,71 +7477,74 @@ namespace Opus // aapt resource value: 0x7f0d00d0 public const int create_mix_from_song = 2131558608; - // aapt resource value: 0x7f0d0113 - public const int create_playlist = 2131558675; + // aapt resource value: 0x7f0d0114 + public const int create_playlist = 2131558676; + + // aapt resource value: 0x7f0d011a + public const int create_synced = 2131558682; // aapt resource value: 0x7f0d0119 - public const int create_synced = 2131558681; + public const int create_youtube = 2131558681; - // aapt resource value: 0x7f0d0118 - public const int create_youtube = 2131558680; - - // aapt resource value: 0x7f0d0143 - public const int dark_theme = 2131558723; + // aapt resource value: 0x7f0d0147 + public const int dark_theme = 2131558727; // aapt resource value: 0x7f0d00db public const int delete = 2131558619; - // aapt resource value: 0x7f0d010b - public const int delete_playlist = 2131558667; + // aapt resource value: 0x7f0d010c + public const int delete_playlist = 2131558668; - // aapt resource value: 0x7f0d0129 - public const int deleted_file = 2131558697; + // aapt resource value: 0x7f0d012d + public const int deleted_file = 2131558701; // aapt resource value: 0x7f0d00d3 public const int download = 2131558611; - // aapt resource value: 0x7f0d0120 - public const int download_albumart = 2131558688; + // aapt resource value: 0x7f0d0124 + public const int download_albumart = 2131558692; - // aapt resource value: 0x7f0d013b - public const int download_directory = 2131558715; + // aapt resource value: 0x7f0d013f + public const int download_directory = 2131558719; - // aapt resource value: 0x7f0d0121 - public const int download_meta = 2131558689; + // aapt resource value: 0x7f0d0125 + public const int download_meta = 2131558693; + + // aapt resource value: 0x7f0d00ee + public const int download_path_error = 2131558638; // aapt resource value: 0x7f0d00ed - public const int download_path_error = 2131558637; - - // aapt resource value: 0x7f0d00ec - public const int download_path_not_set = 2131558636; - - // aapt resource value: 0x7f0d0128 - public const int download_queue = 2131558696; + public const int download_path_not_set = 2131558637; // aapt resource value: 0x7f0d012c - public const int downloader_playlist = 2131558700; + public const int download_queue = 2131558700; - // aapt resource value: 0x7f0d00ef - public const int downloading = 2131558639; + // aapt resource value: 0x7f0d0130 + public const int downloader_playlist = 2131558704; - // aapt resource value: 0x7f0d015d - public const int downloading_notification = 2131558749; + // aapt resource value: 0x7f0d00f0 + public const int downloading = 2131558640; - // aapt resource value: 0x7f0d012d - public const int downloading_status = 2131558701; + // aapt resource value: 0x7f0d0161 + public const int downloading_notification = 2131558753; - // aapt resource value: 0x7f0d015a - public const int downloading_update = 2131558746; + // aapt resource value: 0x7f0d0131 + public const int downloading_status = 2131558705; + + // aapt resource value: 0x7f0d015e + public const int downloading_update = 2131558750; // aapt resource value: 0x7f0d00d2 public const int edit_metadata = 2131558610; - // aapt resource value: 0x7f0d0101 - public const int element = 2131558657; - // aapt resource value: 0x7f0d0102 - public const int elements = 2131558658; + public const int element = 2131558658; + + // aapt resource value: 0x7f0d0103 + public const int elements = 2131558659; + + // aapt resource value: 0x7f0d00e6 + public const int empty_queue = 2131558630; // aapt resource value: 0x7f0d0090 public const int exo_controls_fastforward_description = 2131558544; @@ -7654,11 +7657,11 @@ namespace Opus // aapt resource value: 0x7f0d00b6 public const int filter = 2131558582; - // aapt resource value: 0x7f0d00e7 - public const int folders = 2131558631; + // aapt resource value: 0x7f0d00e8 + public const int folders = 2131558632; - // aapt resource value: 0x7f0d0127 - public const int format_unsupported = 2131558695; + // aapt resource value: 0x7f0d012b + public const int format_unsupported = 2131558699; // aapt resource value: 0x7f0d0086 public const int hide_bottom_view_on_scroll_behavior = 2131558534; @@ -7672,53 +7675,56 @@ namespace Opus // aapt resource value: 0x7f0d00c2 public const int hours = 2131558594; - // aapt resource value: 0x7f0d012a - public const int initialization = 2131558698; + // aapt resource value: 0x7f0d012e + public const int initialization = 2131558702; - // aapt resource value: 0x7f0d0136 - public const int later = 2131558710; + // aapt resource value: 0x7f0d013a + public const int later = 2131558714; // aapt resource value: 0x7f0d00d6 public const int list_songs = 2131558614; - // aapt resource value: 0x7f0d00ea - public const int lives = 2131558634; + // aapt resource value: 0x7f0d00eb + public const int lives = 2131558635; // aapt resource value: 0x7f0d00c7 public const int loading = 2131558599; - // aapt resource value: 0x7f0d00fe - public const int local_playlist_empty = 2131558654; + // aapt resource value: 0x7f0d00ff + public const int local_playlist_empty = 2131558655; - // aapt resource value: 0x7f0d00f9 - public const int local_playlists = 2131558649; + // aapt resource value: 0x7f0d00fa + public const int local_playlists = 2131558650; - // aapt resource value: 0x7f0d0100 - public const int localpl_noperm = 2131558656; + // aapt resource value: 0x7f0d0101 + public const int localpl_noperm = 2131558657; - // aapt resource value: 0x7f0d014a - public const int log_in = 2131558730; + // aapt resource value: 0x7f0d014e + public const int log_in = 2131558734; - // aapt resource value: 0x7f0d014b - public const int log_out = 2131558731; + // aapt resource value: 0x7f0d014f + public const int log_out = 2131558735; - // aapt resource value: 0x7f0d0149 - public const int logged_in = 2131558729; + // aapt resource value: 0x7f0d014d + public const int logged_in = 2131558733; - // aapt resource value: 0x7f0d014c - public const int login_disabled = 2131558732; + // aapt resource value: 0x7f0d0150 + public const int login_disabled = 2131558736; - // aapt resource value: 0x7f0d013c - public const int max_download = 2131558716; + // aapt resource value: 0x7f0d011b + public const int long_loading = 2131558683; - // aapt resource value: 0x7f0d013d - public const int max_download_dialog = 2131558717; + // aapt resource value: 0x7f0d0140 + public const int max_download = 2131558720; - // aapt resource value: 0x7f0d012b - public const int metadata = 2131558699; + // aapt resource value: 0x7f0d0141 + public const int max_download_dialog = 2131558721; - // aapt resource value: 0x7f0d0124 - public const int metdata_error_noid = 2131558692; + // aapt resource value: 0x7f0d012f + public const int metadata = 2131558703; + + // aapt resource value: 0x7f0d0128 + public const int metdata_error_noid = 2131558696; // aapt resource value: 0x7f0d00bf public const int minute = 2131558591; @@ -7729,11 +7735,11 @@ namespace Opus // aapt resource value: 0x7f0d00e3 public const int more = 2131558627; - // aapt resource value: 0x7f0d0125 - public const int mount_error = 2131558693; + // aapt resource value: 0x7f0d0129 + public const int mount_error = 2131558697; - // aapt resource value: 0x7f0d0126 - public const int mount_error_action = 2131558694; + // aapt resource value: 0x7f0d012a + public const int mount_error_action = 2131558698; // aapt resource value: 0x7f0d0040 public const int mr_button_content_description = 2131558464; @@ -7810,44 +7816,44 @@ namespace Opus // aapt resource value: 0x7f0d0087 public const int mtrl_chip_close_icon_content_description = 2131558535; - // aapt resource value: 0x7f0d0116 - public const int new_playlist = 2131558678; + // aapt resource value: 0x7f0d0117 + public const int new_playlist = 2131558679; // aapt resource value: 0x7f0d00bc public const int next_loading = 2131558588; - // aapt resource value: 0x7f0d0138 - public const int no = 2131558712; + // aapt resource value: 0x7f0d013c + public const int no = 2131558716; + + // aapt resource value: 0x7f0d00f7 + public const int no_channel = 2131558647; // aapt resource value: 0x7f0d00f6 - public const int no_channel = 2131558646; + public const int no_lives = 2131558646; + + // aapt resource value: 0x7f0d0152 + public const int no_permission = 2131558738; // aapt resource value: 0x7f0d00f5 - public const int no_lives = 2131558645; - - // aapt resource value: 0x7f0d014e - public const int no_permission = 2131558734; - - // aapt resource value: 0x7f0d00f4 - public const int no_playlist = 2131558644; - - // aapt resource value: 0x7f0d00f2 - public const int no_result = 2131558642; - - // aapt resource value: 0x7f0d00e8 - public const int no_song = 2131558632; - - // aapt resource value: 0x7f0d014f - public const int no_song_mix = 2131558735; + public const int no_playlist = 2131558645; // aapt resource value: 0x7f0d00f3 - public const int no_track = 2131558643; + public const int no_result = 2131558643; - // aapt resource value: 0x7f0d0148 - public const int not_log = 2131558728; + // aapt resource value: 0x7f0d00e9 + public const int no_song = 2131558633; - // aapt resource value: 0x7f0d0154 - public const int not_streamable = 2131558740; + // aapt resource value: 0x7f0d0153 + public const int no_song_mix = 2131558739; + + // aapt resource value: 0x7f0d00f4 + public const int no_track = 2131558644; + + // aapt resource value: 0x7f0d014c + public const int not_log = 2131558732; + + // aapt resource value: 0x7f0d0158 + public const int not_streamable = 2131558744; // aapt resource value: 0x7f0d00bb public const int nothing = 2131558587; @@ -7855,14 +7861,14 @@ namespace Opus // aapt resource value: 0x7f0d00be public const int off = 2131558590; - // aapt resource value: 0x7f0d0134 - public const int ok = 2131558708; + // aapt resource value: 0x7f0d0138 + public const int ok = 2131558712; // aapt resource value: 0x7f0d00c4 public const int open_youtube = 2131558596; - // aapt resource value: 0x7f0d0145 - public const int others = 2131558725; + // aapt resource value: 0x7f0d0149 + public const int others = 2131558729; // aapt resource value: 0x7f0d0088 public const int password_toggle_content_description = 2131558536; @@ -7882,8 +7888,8 @@ namespace Opus // aapt resource value: 0x7f0d00c6 public const int paused = 2131558598; - // aapt resource value: 0x7f0d011f - public const int pick_album_local = 2131558687; + // aapt resource value: 0x7f0d0123 + public const int pick_album_local = 2131558691; // aapt resource value: 0x7f0d00cd public const int play = 2131558605; @@ -7900,29 +7906,29 @@ namespace Opus // aapt resource value: 0x7f0d00c5 public const int playing = 2131558597; - // aapt resource value: 0x7f0d010a - public const int playlist_add_song_not_found = 2131558666; - - // aapt resource value: 0x7f0d0107 - public const int playlist_already_saved = 2131558663; - - // aapt resource value: 0x7f0d0103 - public const int playlist_empty = 2131558659; - - // aapt resource value: 0x7f0d0110 - public const int playlist_fork = 2131558672; - - // aapt resource value: 0x7f0d0109 - public const int playlist_not_found = 2131558665; - - // aapt resource value: 0x7f0d0106 - public const int playlist_saved = 2131558662; + // aapt resource value: 0x7f0d010b + public const int playlist_add_song_not_found = 2131558667; // aapt resource value: 0x7f0d0108 - public const int playlist_unsaved = 2131558664; + public const int playlist_already_saved = 2131558664; - // aapt resource value: 0x7f0d0112 - public const int playlist_uptodate = 2131558674; + // aapt resource value: 0x7f0d0104 + public const int playlist_empty = 2131558660; + + // aapt resource value: 0x7f0d0111 + public const int playlist_fork = 2131558673; + + // aapt resource value: 0x7f0d010a + public const int playlist_not_found = 2131558666; + + // aapt resource value: 0x7f0d0107 + public const int playlist_saved = 2131558663; + + // aapt resource value: 0x7f0d0109 + public const int playlist_unsaved = 2131558665; + + // aapt resource value: 0x7f0d0113 + public const int playlist_uptodate = 2131558675; // aapt resource value: 0x7f0d00b3 public const int playlists = 2131558579; @@ -7933,23 +7939,23 @@ namespace Opus // aapt resource value: 0x7f0d00d8 public const int random_play = 2131558616; - // aapt resource value: 0x7f0d00f8 - public const int remove = 2131558648; + // aapt resource value: 0x7f0d00f9 + public const int remove = 2131558649; - // aapt resource value: 0x7f0d0104 - public const int remove_from_playlist = 2131558660; + // aapt resource value: 0x7f0d0105 + public const int remove_from_playlist = 2131558661; // aapt resource value: 0x7f0d00d4 public const int remove_from_queue = 2131558612; - // aapt resource value: 0x7f0d00f7 - public const int remove_search = 2131558647; + // aapt resource value: 0x7f0d00f8 + public const int remove_search = 2131558648; // aapt resource value: 0x7f0d00d5 public const int remove_track_from_playlist = 2131558613; - // aapt resource value: 0x7f0d0105 - public const int removed_from_playlist = 2131558661; + // aapt resource value: 0x7f0d0106 + public const int removed_from_playlist = 2131558662; // aapt resource value: 0x7f0d00c8 public const int removed_from_queue = 2131558600; @@ -7957,8 +7963,8 @@ namespace Opus // aapt resource value: 0x7f0d00da public const int rename = 2131558618; - // aapt resource value: 0x7f0d010c - public const int rename_playlist = 2131558668; + // aapt resource value: 0x7f0d010d + public const int rename_playlist = 2131558669; // aapt resource value: 0x7f0d00b4 public const int repeat = 2131558580; @@ -7966,17 +7972,17 @@ namespace Opus // aapt resource value: 0x7f0d00c9 public const int save_as_playlist = 2131558601; - // aapt resource value: 0x7f0d0115 - public const int save_folder_playlist = 2131558677; + // aapt resource value: 0x7f0d0116 + public const int save_folder_playlist = 2131558678; - // aapt resource value: 0x7f0d0114 - public const int save_playlist = 2131558676; + // aapt resource value: 0x7f0d0115 + public const int save_playlist = 2131558677; // aapt resource value: 0x7f0d0073 public const int search_menu_title = 2131558515; - // aapt resource value: 0x7f0d00ee - public const int set_path = 2131558638; + // aapt resource value: 0x7f0d00ef + public const int set_path = 2131558639; // aapt resource value: 0x7f0d00b8 public const int settings = 2131558584; @@ -7993,8 +7999,8 @@ namespace Opus // aapt resource value: 0x7f0d00bd public const int sleep_timer = 2131558589; - // aapt resource value: 0x7f0d00e6 - public const int songs = 2131558630; + // aapt resource value: 0x7f0d00e7 + public const int songs = 2131558631; // aapt resource value: 0x7f0d008d public const int status_bar_notification_info_overflow = 2131558541; @@ -8002,8 +8008,8 @@ namespace Opus // aapt resource value: 0x7f0d00de public const int stop_sync = 2131558622; - // aapt resource value: 0x7f0d010d - public const int stop_syncing = 2131558669; + // aapt resource value: 0x7f0d010e + public const int stop_syncing = 2131558670; // aapt resource value: 0x7f0d003d public const int summary_collapsed_preference_list = 2131558461; @@ -8014,65 +8020,65 @@ namespace Opus // aapt resource value: 0x7f0d00dd public const int sync_now = 2131558621; - // aapt resource value: 0x7f0d013e - public const int sync_remove = 2131558718; + // aapt resource value: 0x7f0d0142 + public const int sync_remove = 2131558722; - // aapt resource value: 0x7f0d00f0 - public const int syncing = 2131558640; + // aapt resource value: 0x7f0d00f1 + public const int syncing = 2131558641; - // aapt resource value: 0x7f0d015e - public const int tap_details = 2131558750; + // aapt resource value: 0x7f0d0162 + public const int tap_details = 2131558754; - // aapt resource value: 0x7f0d0140 - public const int theme = 2131558720; + // aapt resource value: 0x7f0d0144 + public const int theme = 2131558724; - // aapt resource value: 0x7f0d0141 - public const int theme_dialog = 2131558721; + // aapt resource value: 0x7f0d0145 + public const int theme_dialog = 2131558725; // aapt resource value: 0x7f0d00c3 public const int timer = 2131558595; + // aapt resource value: 0x7f0d0155 + public const int timout = 2131558741; + + // aapt resource value: 0x7f0d011e + public const int title = 2131558686; + // aapt resource value: 0x7f0d0151 - public const int timout = 2131558737; + public const int undo = 2131558737; - // aapt resource value: 0x7f0d011a - public const int title = 2131558682; - - // aapt resource value: 0x7f0d014d - public const int undo = 2131558733; - - // aapt resource value: 0x7f0d0122 - public const int undo_change = 2131558690; + // aapt resource value: 0x7f0d0126 + public const int undo_change = 2131558694; // aapt resource value: 0x7f0d00e0 public const int unfork = 2131558624; - // aapt resource value: 0x7f0d010e - public const int unfork_playlist = 2131558670; + // aapt resource value: 0x7f0d010f + public const int unfork_playlist = 2131558671; - // aapt resource value: 0x7f0d0152 - public const int unknow = 2131558738; + // aapt resource value: 0x7f0d0156 + public const int unknow = 2131558742; // aapt resource value: 0x7f0d00ba public const int up_next = 2131558586; - // aapt resource value: 0x7f0d0158 - public const int up_to_date = 2131558744; + // aapt resource value: 0x7f0d015c + public const int up_to_date = 2131558748; - // aapt resource value: 0x7f0d012e - public const int up_to_date_status = 2131558702; + // aapt resource value: 0x7f0d0132 + public const int up_to_date_status = 2131558706; - // aapt resource value: 0x7f0d0156 - public const int update = 2131558742; - - // aapt resource value: 0x7f0d0157 - public const int update_message = 2131558743; - - // aapt resource value: 0x7f0d0155 - public const int update_no_internet = 2131558741; + // aapt resource value: 0x7f0d015a + public const int update = 2131558746; // aapt resource value: 0x7f0d015b - public const int updating = 2131558747; + public const int update_message = 2131558747; + + // aapt resource value: 0x7f0d0159 + public const int update_no_internet = 2131558745; + + // aapt resource value: 0x7f0d015f + public const int updating = 2131558751; // aapt resource value: 0x7f0d003e public const int v7_preference_off = 2131558462; @@ -8080,38 +8086,44 @@ namespace Opus // aapt resource value: 0x7f0d003f public const int v7_preference_on = 2131558463; - // aapt resource value: 0x7f0d0147 - public const int version = 2131558727; + // aapt resource value: 0x7f0d014b + public const int version = 2131558731; - // aapt resource value: 0x7f0d013a - public const int volume = 2131558714; + // aapt resource value: 0x7f0d011d + public const int view_less = 2131558685; - // aapt resource value: 0x7f0d0142 - public const int white_theme = 2131558722; + // aapt resource value: 0x7f0d011c + public const int view_more = 2131558684; - // aapt resource value: 0x7f0d0137 - public const int yes = 2131558711; + // aapt resource value: 0x7f0d013e + public const int volume = 2131558718; - // aapt resource value: 0x7f0d0150 - public const int youtube_endpoint = 2131558736; + // aapt resource value: 0x7f0d0146 + public const int white_theme = 2131558726; - // aapt resource value: 0x7f0d00fc - public const int youtube_loading_error = 2131558652; + // aapt resource value: 0x7f0d013b + public const int yes = 2131558715; + + // aapt resource value: 0x7f0d0154 + public const int youtube_endpoint = 2131558740; // aapt resource value: 0x7f0d00fd - public const int youtube_not_logged = 2131558653; + public const int youtube_loading_error = 2131558653; - // aapt resource value: 0x7f0d00ff - public const int youtube_playlist_empty = 2131558655; + // aapt resource value: 0x7f0d00fe + public const int youtube_not_logged = 2131558654; - // aapt resource value: 0x7f0d00fa - public const int youtube_playlists = 2131558650; + // aapt resource value: 0x7f0d0100 + public const int youtube_playlist_empty = 2131558656; + + // aapt resource value: 0x7f0d00fb + public const int youtube_playlists = 2131558651; // aapt resource value: 0x7f0d00b5 public const int youtube_search = 2131558581; - // aapt resource value: 0x7f0d011d - public const int youtubeid = 2131558685; + // aapt resource value: 0x7f0d0121 + public const int youtubeid = 2131558689; // aapt resource value: 0x7f0d00b0 public const int yt_api_key = 2131558576; diff --git a/Opus/Resources/layout/HomeChannels.xml b/Opus/Resources/layout/HomeChannels.xml index a4dcbd1..d20024d 100644 --- a/Opus/Resources/layout/HomeChannels.xml +++ b/Opus/Resources/layout/HomeChannels.xml @@ -21,6 +21,7 @@