Starting the creation of a channel view.

This commit is contained in:
Anonymus Raccoon
2019-06-24 00:22:47 +02:00
parent 4135b493c5
commit 1661e9f6b1
17 changed files with 493 additions and 147 deletions

View File

@@ -229,7 +229,7 @@ namespace Opus.Api.Services
if (queue.Count == 1)
SetNotificationProgress(100, true);
SetMetaData(position, video.Title, video.Author, new string[] { video.Thumbnails.MaxResUrl, video.Thumbnails.StandardResUrl, video.Thumbnails.HighResUrl });
SetMetaData(position, video.Title, video.Author, video.Thumbnails);
files.Remove(filePath);
downloadCount--;
@@ -256,7 +256,7 @@ namespace Opus.Api.Services
}
}
private async void SetMetaData(int position, string title, string artist, string[] thumbnails)
private async void SetMetaData(int position, string title, string artist, ThumbnailSet thumbnails)
{
string filePath = queue[position].Path;

View File

@@ -160,7 +160,7 @@ namespace Opus.Code.Api
Video video = await client.GetVideoAsync(song.YoutubeID);
song.Title = video.Title;
song.Artist = video.Author;
song.Album = await YoutubeManager.GetBestThumb(new string[] { video.Thumbnails.MaxResUrl, video.Thumbnails.StandardResUrl, video.Thumbnails.HighResUrl });
song.Album = await YoutubeManager.GetBestThumb(video.Thumbnails);
song.Duration = (int)video.Duration.TotalMilliseconds;
if (queuePosition == MusicPlayer.CurrentID())

View File

@@ -407,7 +407,7 @@ namespace Opus.Api
foreach (var video in searchReponse.Items)
{
Song song = new Song(System.Net.WebUtility.HtmlDecode(video.Snippet.Title), video.Snippet.ChannelTitle, video.Snippet.Thumbnails.High.Url, video.Id.VideoId, -1, -1, null, true, false);
Song song = new Song(WebUtility.HtmlDecode(video.Snippet.Title), video.Snippet.ChannelTitle, video.Snippet.Thumbnails.High.Url, video.Id.VideoId, -1, -1, null, true, false);
songs.Add(song);
}
}
@@ -432,10 +432,11 @@ namespace Opus.Api
/// <summary>
/// Return the thumbnail with the greatest quality.
/// </summary>
/// <param name="thumbnails">This array should contains the urls of the thumbnails in this order: MaxResUrl, StandardResUrl, HighResUrl</param>
/// <param name="thumbnails">This will create an array of the thumbnails in this order: MaxResUrl, StandardResUrl, HighResUrl</param>
/// <returns></returns>
public async static Task<string> GetBestThumb(string[] thumbnails)
public async static Task<string> GetBestThumb(ThumbnailSet Thumbnails)
{
string[] thumbnails = new string[] { Thumbnails.MaxResUrl, Thumbnails.StandardResUrl, Thumbnails.HighResUrl };
foreach (string thumb in thumbnails)
{
HttpWebRequest request = new HttpWebRequest(new Uri(thumb))

View File

@@ -4,33 +4,41 @@ using System.Collections.Generic;
namespace Opus.DataStructure
{
[System.Serializable]
public class HomeSection
public class Section
{
public string SectionTitle;
public SectionType contentType;
public List<Song> contentValue;
public List<PlaylistItem> playlistContent;
public List<Channel> channelContent;
public RecyclerView recycler;
public HomeSection(string sectionTitle, SectionType contentType)
public Section(string sectionTitle, SectionType contentType)
{
SectionTitle = sectionTitle;
this.contentType = contentType;
}
public HomeSection(string sectionTitle, SectionType contentType, List<Song> contentValue)
public Section(string sectionTitle, SectionType contentType, List<Song> contentValue)
{
SectionTitle = sectionTitle;
this.contentType = contentType;
this.contentValue = contentValue;
}
public HomeSection(string sectionTitle, SectionType contentType, List<PlaylistItem> playlistContent)
public Section(string sectionTitle, SectionType contentType, List<PlaylistItem> playlistContent)
{
SectionTitle = sectionTitle;
this.contentType = contentType;
this.playlistContent = playlistContent;
}
public Section(string sectionTitle, SectionType contentType, List<Channel> channelContent)
{
SectionTitle = sectionTitle;
this.contentType = contentType;
this.channelContent = channelContent;
}
}
public enum SectionType

View File

@@ -8,6 +8,7 @@ using Newtonsoft.Json;
using Opus.Fragments;
using SQLite;
using System;
using System.Collections.Generic;
namespace Opus.DataStructure
{
@@ -78,6 +79,21 @@ namespace Opus.DataStructure
return new Song(Title, playOrder ?? Artist, Album, null, AlbumArt, id, path);
}
public static explicit operator Song(YoutubeExplode.Models.Video video)
{
return new Song(video.Title, video.Author, video.Thumbnails.HighResUrl, video.Id, -1, -1, null, true, false);
}
public static List<Song> FromVideoArray(IReadOnlyList<YoutubeExplode.Models.Video> videos)
{
List<Song> songs = new List<Song>();
for (int i = 0; i < videos.Count; i++)
{
songs.Add((Song)videos[i]);
}
return songs;
}
public static explicit operator Song(string v)
{

View File

@@ -50,7 +50,6 @@ namespace Opus
public class MainActivity : AppCompatActivity, GoogleApiClient.IOnConnectionFailedListener, IResultCallback, IMenuItemOnActionExpandListener, View.IOnFocusChangeListener, ISessionManagerListener
{
public static MainActivity instance;
//public new static int Theme = 1;
public static int dialogTheme;
public bool NoToolbarMenu = false;

View File

@@ -150,7 +150,7 @@ namespace Opus.Adapter
Color color;
TypedValue value = new TypedValue();
if (MainActivity.instance.Theme.ResolveAttribute(Resource.Styleable.TextAppearance_android_textColor, value, true))
if (MainActivity.instance.Theme.ResolveAttribute(Android.Resource.Attribute.TextColor, value, true))
color = Color.ParseColor("#" + Java.Lang.Integer.ToHexString(value.Data));
else
color = Color.Black;

View File

@@ -11,16 +11,16 @@ using System.Collections.Generic;
namespace Opus.Adapter
{
public class HomeAdapter : RecyclerView.Adapter
public class SectionAdapter : RecyclerView.Adapter
{
public List<HomeSection> items;
public List<Section> items;
private bool refreshDisabled = true;
public event EventHandler<int> ItemClick;
public event EventHandler<int> ItemLongClick;
public HomeAdapter(List<HomeSection> items)
public SectionAdapter(List<Section> items)
{
this.items = items;
}
@@ -73,6 +73,11 @@ namespace Opus.Adapter
if(MusicPlayer.CurrentID() != -1 && MusicPlayer.CurrentID() <= MusicPlayer.queue.Count)
holder.recycler.ScrollToPosition(MusicPlayer.CurrentID());
}
else if(items[position].SectionTitle == null)
{
//The playlist is loading
holder.recycler.SetAdapter(new LineAdapter(new List<Song>(), holder.recycler));
}
else
{
holder.title.Text = items[position].SectionTitle;
@@ -80,8 +85,8 @@ namespace Opus.Adapter
holder.more.Click += (sender, e) =>
{
position = holder.AdapterPosition;
MainActivity.instance.contentRefresh.Refresh -= Home.instance.OnRefresh;
Home.instance = null;
//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();
};
}
@@ -139,13 +144,6 @@ namespace Opus.Adapter
// };
//}
//else if (items[position].contentType == SectionType.Shuffle)
//{
// if (MainActivity.Theme == 1)
// ((CardView)viewHolder.ItemView).SetCardBackgroundColor(Color.ParseColor("#212121"));
// else
// ((CardView)viewHolder.ItemView).SetCardBackgroundColor(Color.White);
//}
}
void OnClick(int position)

View File

@@ -0,0 +1,317 @@
using Android.Content;
using Android.Database;
using Android.Net;
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.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 static ChannelDetails instance;
private Channel item;
private TextView EmptyView;
private RecyclerView ListView;
private SectionAdapter adapter;
private List<Section> sections = new List<Section>();
public override void OnActivityCreated(Bundle savedInstanceState)
{
base.OnActivityCreated(savedInstanceState);
if (item == null)
{
MainActivity.instance.SupportFragmentManager.PopBackStack();
return;
}
MainActivity.instance.contentRefresh.Refresh += OnRefresh;
MainActivity.instance.DisplaySearch();
MainActivity.instance.SupportActionBar.SetHomeButtonEnabled(true);
MainActivity.instance.SupportActionBar.SetDisplayHomeAsUpEnabled(true);
MainActivity.instance.SupportActionBar.SetDisplayShowTitleEnabled(true);
MainActivity.instance.FindViewById(Resource.Id.toolbarLogo).Visibility = ViewStates.Gone;
MainActivity.instance.SupportActionBar.Title = item.Name;
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.LonelyRecycler, container, false);
ListView = view.FindViewById<RecyclerView>(Resource.Id.recycler);
ListView.SetLayoutManager(new Android.Support.V7.Widget.LinearLayoutManager(MainActivity.instance));
if(item != null)
CreateHeader();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
PopulateList();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
return view;
}
void CreateHeader()
{
Activity.FindViewById<RelativeLayout>(Resource.Id.playlistHeader).Visibility = ViewStates.Visible;
((AppBarLayout.LayoutParams)Activity.FindViewById<CollapsingToolbarLayout>(Resource.Id.collapsingToolbar).LayoutParameters).ScrollFlags = AppBarLayout.LayoutParams.ScrollFlagScroll | AppBarLayout.LayoutParams.ScrollFlagExitUntilCollapsed;
Activity.FindViewById<AppBarLayout>(Resource.Id.appbar).AddOnOffsetChangedListener(this);
Activity.FindViewById<TextView>(Resource.Id.headerTitle).Text = item.Name;
Activity.FindViewById<TextView>(Resource.Id.headerAuthor).Text = null;
Activity.FindViewById<TextView>(Resource.Id.headerNumber).Text = null;
Activity.FindViewById(Resource.Id.playlistButtons).Visibility = ViewStates.Gone;
Picasso.With(Android.App.Application.Context).Load(item.ImageURL).Placeholder(Resource.Drawable.noAlbum).Transform(new RemoveBlackBorder(true)).Into(Activity.FindViewById<ImageView>(Resource.Id.headerArt));
Activity.FindViewById(Resource.Id.collapsingToolbar).RequestLayout();
}
public override void OnDestroyView()
{
//MainActivity.instance.RemoveFilterListener(Search);
if (!MainActivity.instance.Paused)
{
Activity.FindViewById(Resource.Id.playlistButtons).Visibility = ViewStates.Visible;
Activity.FindViewById<RelativeLayout>(Resource.Id.playlistHeader).Visibility = ViewStates.Gone;
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.contentRefresh.Refresh -= OnRefresh;
Activity.FindViewById<AppBarLayout>(Resource.Id.appbar).RemoveOnOffsetChangedListener(this);
if (YoutubeSearch.instances != null)
{
MainActivity.instance.FindViewById<TabLayout>(Resource.Id.tabs).Visibility = ViewStates.Visible;
SearchView searchView = (SearchView)MainActivity.instance.menu.FindItem(Resource.Id.search).ActionView;
searchView.Focusable = false;
MainActivity.instance.menu.FindItem(Resource.Id.search).ExpandActionView();
searchView.SetQuery(YoutubeSearch.instances[0].Query, false);
searchView.ClearFocus();
int selectedTab = 0;
for (int i = 0; i < YoutubeSearch.instances.Length; i++)
{
if (YoutubeSearch.instances[i].IsFocused)
selectedTab = i;
}
}
instance = null;
}
base.OnDestroyView();
}
public static Fragment NewInstance(Channel item)
{
instance = new ChannelDetails { Arguments = new Bundle() };
instance.item = item;
return instance;
}
async Task PopulateList()
{
sections.Clear();
try
{
var request = YoutubeManager.YoutubeService.ChannelSections.List("snippet,contentDetails");
request.ChannelId = item.YoutubeID;
var response = await request.ExecuteAsync();
for (int i = 0; i < response.Items.Count; i++)
{
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<PlaylistItem>()));
//else if (item.ContentDetails.Channels.Count > 1)
// sections.Add(new Section(item.Snippet.Title, SectionType.ChannelList, new List<Channel>()));
}
adapter = new SectionAdapter(sections);
ListView.SetAdapter(adapter);
}
catch (System.Net.Http.HttpRequestException) { System.Console.WriteLine("&Channel section list time out"); }
}
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));
adapter.NotifyItemChanged(slot);
}
public async void OnRefresh(object sender, System.EventArgs e)
{
await PopulateList();
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<TextView>(Resource.Id.bsTitle).Text = song.Title;
//bottomView.FindViewById<TextView>(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<ImageView>(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<ImageView>(Resource.Id.bsArt));
//}
//bottomSheet.SetContentView(bottomView);
//List<BottomSheetAction> actions = new List<BottomSheetAction>
//{
// 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<ListView>(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<ImageButton>(Resource.Id.headerPlay).HasOnClickListeners)
// Activity.FindViewById<ImageButton>(Resource.Id.headerPlay).Click += (sender, e0) => { PlaylistManager.PlayInOrder(item); };
//if (!Activity.FindViewById<ImageButton>(Resource.Id.headerShuffle).HasOnClickListeners)
// Activity.FindViewById<ImageButton>(Resource.Id.headerShuffle).Click += (sender, e0) => { PlaylistManager.Shuffle(item); };
//if (!Activity.FindViewById<ImageButton>(Resource.Id.headerMore).HasOnClickListeners)
// Activity.FindViewById<ImageButton>(Resource.Id.headerMore).Click += PlaylistMore;
}
public void OnOffsetChanged(AppBarLayout appBarLayout, int verticalOffset)
{
if (instance == null)
return;
if (System.Math.Abs(verticalOffset) <= appBarLayout.TotalScrollRange - MainActivity.instance.FindViewById<Toolbar>(Resource.Id.toolbar).Height)
{
Activity.FindViewById<RelativeLayout>(Resource.Id.playlistHeader).Visibility = ViewStates.Visible;
MainActivity.instance.SupportActionBar.SetDisplayShowTitleEnabled(false);
}
else
{
Activity.FindViewById<RelativeLayout>(Resource.Id.playlistHeader).Visibility = ViewStates.Invisible;
MainActivity.instance.SupportActionBar.SetDisplayShowTitleEnabled(true);
}
}
public override void OnDestroy()
{
base.OnDestroy();
MainActivity.instance.FindViewById(Resource.Id.toolbarLogo).Visibility = ViewStates.Visible;
}
}
}

View File

@@ -346,7 +346,7 @@ namespace Opus.Fragments
album.Text = video.Title + " - " + video.Author;
}
ytThumbUri = await YoutubeManager.GetBestThumb(new string[] { video.Thumbnails.MaxResUrl, video.Thumbnails.StandardResUrl, video.Thumbnails.HighResUrl });
ytThumbUri = await YoutubeManager.GetBestThumb(video.Thumbnails);
Picasso.With(this).Load(ytThumbUri).Placeholder(Resource.Drawable.noAlbum).Transform(new RemoveBlackBorder(true)).MemoryPolicy(MemoryPolicy.NoCache, MemoryPolicy.NoStore).Into(albumArt);
}

View File

@@ -22,10 +22,10 @@ namespace Opus.Fragments
{
public static Home instance;
public RecyclerView ListView;
public HomeAdapter adapter;
public SectionAdapter adapter;
public LineAdapter QueueAdapter;
public ItemTouchHelper itemTouchHelper;
public static List<HomeSection> adapterItems = new List<HomeSection>();
public static List<Section> adapterItems = new List<Section>();
public List<string> selectedTopics = new List<string>();
public List<string> selectedTopicsID = new List<string>();
public View view;
@@ -69,15 +69,15 @@ namespace Opus.Fragments
if (!populating)
{
populating = true;
adapterItems = new List<HomeSection>();
adapterItems = new List<Section>();
if (MusicPlayer.UseCastPlayer || (MusicPlayer.queue != null && MusicPlayer.queue?.Count > 0))
{
HomeSection queue = new HomeSection("Queue", SectionType.SinglePlaylist, MusicPlayer.queue);
Section queue = new Section("Queue", SectionType.SinglePlaylist, MusicPlayer.queue);
adapterItems.Add(queue);
}
HomeSection shuffle = new HomeSection(Resources.GetString(Resource.String.shuffle), SectionType.Shuffle);
Section shuffle = new Section(Resources.GetString(Resource.String.shuffle), SectionType.Shuffle);
adapterItems.Add(shuffle);
await Task.Run(() =>
@@ -126,14 +126,14 @@ namespace Opus.Fragments
if (songList.Count > 0)
{
HomeSection featured = new HomeSection(Resources.GetString(Resource.String.featured), SectionType.SinglePlaylist, songList.GetRange(0, songList.Count > 50 ? 50 : songList.Count));
Section featured = new Section(Resources.GetString(Resource.String.featured), SectionType.SinglePlaylist, songList.GetRange(0, songList.Count > 50 ? 50 : songList.Count));
adapterItems.Add(featured);
}
}
});
view.FindViewById(Resource.Id.loading).Visibility = ViewStates.Gone;
adapter = new HomeAdapter(adapterItems);
adapter = new SectionAdapter(adapterItems);
ListView.SetAdapter(adapter);
adapter.ItemClick += ListView_ItemClick;
ListView.SetItemAnimator(new DefaultItemAnimator());
@@ -146,7 +146,7 @@ namespace Opus.Fragments
sp.AddRange(saved);
sp.AddRange(pl);
adapterItems.Add(new HomeSection(GetString(Resource.String.playlists), SectionType.PlaylistList, sp));
adapterItems.Add(new Section(GetString(Resource.String.playlists), SectionType.PlaylistList, sp));
adapter.NotifyItemInserted(adapterItems.Count - 1);
}
else
@@ -155,7 +155,7 @@ namespace Opus.Fragments
if(saved != null && saved.Count > 0)
{
adapterItems.Add(new HomeSection(GetString(Resource.String.playlists), SectionType.PlaylistList, saved));
adapterItems.Add(new Section(GetString(Resource.String.playlists), SectionType.PlaylistList, saved));
adapter.NotifyItemInserted(adapterItems.Count - 1);
}
}
@@ -168,7 +168,7 @@ namespace Opus.Fragments
{
if (adapterItems[0].SectionTitle != "Queue")
{
HomeSection queue = new HomeSection("Queue", SectionType.SinglePlaylist, MusicPlayer.queue);
Section queue = new Section("Queue", SectionType.SinglePlaylist, MusicPlayer.queue);
adapterItems.Insert(0, queue);
adapter?.NotifyItemInserted(0);
}

View File

@@ -157,7 +157,7 @@ namespace Opus.Fragments
if (YoutubeSearch.instances != null)
{
MainActivity.instance.FindViewById<TabLayout>(Resource.Id.tabs).Visibility = ViewStates.Visible;
Android.Support.V7.Widget.SearchView searchView = (Android.Support.V7.Widget.SearchView)MainActivity.instance.menu.FindItem(Resource.Id.search).ActionView;
SearchView searchView = (SearchView)MainActivity.instance.menu.FindItem(Resource.Id.search).ActionView;
searchView.Focusable = false;
MainActivity.instance.menu.FindItem(Resource.Id.search).ExpandActionView();
searchView.SetQuery(YoutubeSearch.instances[0].Query, false);
@@ -272,7 +272,7 @@ namespace Opus.Fragments
instance = new PlaylistTracks { Arguments = new Bundle() };
instance.item = item;
instance.useHeader = true;
instance.isInEditMode = true;
instance.isInEditMode = item.HasWritePermission && item.LocalID != 0;
instance.fullyLoadded = item.LocalID != 0 && item.LocalID != -1;
Task.Run(async () =>
@@ -356,15 +356,9 @@ namespace Opus.Fragments
Uri musicUri = Playlists.Members.GetContentUri("external", item.LocalID);
string selection;
if (query != null)
{
selection = Media.InterfaceConsts.Title + " LIKE \"%" + query + "%\" OR " + Media.InterfaceConsts.Artist + " LIKE \"%" + query + "%\"";
isInEditMode = false;
}
else
{
selection = null;
isInEditMode = true;
}
return new CursorLoader(Android.App.Application.Context, musicUri, null, selection, null, Playlists.Members.PlayOrder);
}
@@ -451,11 +445,17 @@ namespace Opus.Fragments
public void Search(object sender, SearchView.QueryTextChangeEventArgs e)
{
if (e.NewText == "")
{
query = null;
isInEditMode = item.HasWritePermission && item.LocalID != 0;
}
else
{
query = e.NewText.ToLower();
isInEditMode = false;
}
if(item.LocalID != -1)
if (item.LocalID != -1)
LoaderManager.GetInstance(this).RestartLoader(0, null, this);
else
{

View File

@@ -293,11 +293,8 @@ namespace Opus.Fragments
catch(Exception ex)
{
Console.WriteLine("&Exception catched in the youtube search: " + ex.Source + " - " + ex.Message);
if(ex is System.Net.Http.HttpRequestException)
{
EmptyView.Text = GetString(Resource.String.timout);
EmptyView.Visibility = ViewStates.Visible;
}
EmptyView.Text = GetString(Resource.String.timout);
EmptyView.Visibility = ViewStates.Visible;
}
}
@@ -340,6 +337,11 @@ namespace Opus.Fragments
MainActivity.instance.FindViewById<TabLayout>(Resource.Id.tabs).Visibility = ViewStates.Gone;
MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(result[position].playlist)).AddToBackStack("Playlist Track").Commit();
break;
case YtKind.Channel:
MainActivity.instance.menu.FindItem(Resource.Id.search).CollapseActionView();
MainActivity.instance.FindViewById<TabLayout>(Resource.Id.tabs).Visibility = ViewStates.Gone;
MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, ChannelDetails.NewInstance(result[position].channel)).AddToBackStack("Channel Details").Commit();
break;
default:
break;
}

View File

@@ -15,7 +15,7 @@ public class CollapsingToolbar : CollapsingToolbarLayout
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
if (PlaylistTracks.instance != null && PlaylistTracks.instance.useHeader)
if ((PlaylistTracks.instance != null && PlaylistTracks.instance.useHeader) ||ChannelDetails.instance != null)
heightMeasureSpec = widthMeasureSpec;

View File

@@ -331,6 +331,7 @@
<Compile Include="Code\Api\PlaylistManager.cs" />
<Compile Include="Code\Api\SongManager.cs" />
<Compile Include="Code\Api\YoutubeManager.cs" />
<Compile Include="Code\UI\Fragments\ChannelDetails.cs" />
<Compile Include="GlobalSuppressions.cs" />
<Compile Include="Code\MainActivity.cs" />
<Compile Include="Code\UI\Views\AccountPreference.cs" />
@@ -364,7 +365,7 @@
<Compile Include="Code\UI\Fragments\FolderTracks.cs" />
<Compile Include="Code\Others\HeadphonesActions.cs" />
<Compile Include="Code\UI\Fragments\Home.cs" />
<Compile Include="Code\UI\Adapter\HomeAdapter.cs" />
<Compile Include="Code\UI\Adapter\SectionAdapter.cs" />
<Compile Include="Code\UI\Adapter\HomeListAdapter.cs" />
<Compile Include="Code\DataStructure\HomeHolder.cs" />
<Compile Include="Code\Others\ItemTouchCallback.cs" />

View File

@@ -4997,8 +4997,8 @@ namespace Opus
// aapt resource value: 0x7f0b0067
public const int META = 2131427431;
// aapt resource value: 0x7f0b01b5
public const int PreferenceScreen = 2131427765;
// aapt resource value: 0x7f0b01b6
public const int PreferenceScreen = 2131427766;
// aapt resource value: 0x7f0b0068
public const int SHIFT = 2131427432;
@@ -5006,8 +5006,8 @@ namespace Opus
// aapt resource value: 0x7f0b0069
public const int SYM = 2131427433;
// aapt resource value: 0x7f0b01b7
public const int accountPreference = 2131427767;
// aapt resource value: 0x7f0b01b8
public const int accountPreference = 2131427768;
// aapt resource value: 0x7f0b00ff
public const int action = 2131427583;
@@ -5093,8 +5093,8 @@ namespace Opus
// aapt resource value: 0x7f0b0059
public const int add = 2131427417;
// aapt resource value: 0x7f0b01d4
public const int addToQueue = 2131427796;
// aapt resource value: 0x7f0b01d5
public const int addToQueue = 2131427797;
// aapt resource value: 0x7f0b00ce
public const int added = 2131427534;
@@ -5117,17 +5117,17 @@ namespace Opus
// aapt resource value: 0x7f0b006a
public const int always = 2131427434;
// aapt resource value: 0x7f0b01bf
public const int apAlbum = 2131427775;
// aapt resource value: 0x7f0b01c0
public const int apAlbum = 2131427776;
// aapt resource value: 0x7f0b01c1
public const int apTitle = 2131427777;
// aapt resource value: 0x7f0b01c2
public const int apTitle = 2131427778;
// aapt resource value: 0x7f0b011b
public const int appbar = 2131427611;
// aapt resource value: 0x7f0b01ad
public const int artist = 2131427757;
// aapt resource value: 0x7f0b01ae
public const int artist = 2131427758;
// aapt resource value: 0x7f0b008f
public const int async = 2131427471;
@@ -5138,8 +5138,8 @@ namespace Opus
// aapt resource value: 0x7f0b004d
public const int auto = 2131427405;
// aapt resource value: 0x7f0b01be
public const int autoplay = 2131427774;
// aapt resource value: 0x7f0b01bf
public const int autoplay = 2131427775;
// aapt resource value: 0x7f0b011f
public const int backToolbar = 2131427615;
@@ -5153,8 +5153,8 @@ namespace Opus
// aapt resource value: 0x7f0b0061
public const int beginning = 2131427425;
// aapt resource value: 0x7f0b01b6
public const int behavior = 2131427766;
// aapt resource value: 0x7f0b01b7
public const int behavior = 2131427767;
// aapt resource value: 0x7f0b0090
public const int blocking = 2131427472;
@@ -5165,14 +5165,14 @@ namespace Opus
// aapt resource value: 0x7f0b006f
public const int bottom = 2131427439;
// aapt resource value: 0x7f0b01bc
public const int bottomDivider = 2131427772;
// aapt resource value: 0x7f0b01bd
public const int bottomDivider = 2131427773;
// aapt resource value: 0x7f0b013a
public const int bottomView = 2131427642;
// aapt resource value: 0x7f0b01cf
public const int browseLayout = 2131427791;
// aapt resource value: 0x7f0b01d0
public const int browseLayout = 2131427792;
// aapt resource value: 0x7f0b00d9
public const int browseList = 2131427545;
@@ -5336,8 +5336,8 @@ namespace Opus
// aapt resource value: 0x7f0b00a0
public const int default_activity_button = 2131427488;
// aapt resource value: 0x7f0b01d1
public const int delete = 2131427793;
// aapt resource value: 0x7f0b01d2
public const int delete = 2131427794;
// aapt resource value: 0x7f0b0110
public const int design_bottom_sheet = 2131427600;
@@ -5366,14 +5366,14 @@ namespace Opus
// aapt resource value: 0x7f0b0045
public const int download = 2131427397;
// aapt resource value: 0x7f0b01d2
public const int downloadMDfromYT = 2131427794;
// aapt resource value: 0x7f0b01d3
public const int downloadMDfromYT = 2131427795;
// aapt resource value: 0x7f0b0118
public const int downloadStatus = 2131427608;
// aapt resource value: 0x7f0b01ae
public const int edit = 2131427758;
// aapt resource value: 0x7f0b01af
public const int edit = 2131427759;
// aapt resource value: 0x7f0b00c0
public const int edit_query = 2131427520;
@@ -5495,8 +5495,8 @@ namespace Opus
// aapt resource value: 0x7f0b0089
public const int filled = 2131427465;
// aapt resource value: 0x7f0b01d6
public const int filter = 2131427798;
// aapt resource value: 0x7f0b01d7
public const int filter = 2131427799;
// aapt resource value: 0x7f0b0094
public const int fit = 2131427476;
@@ -5537,17 +5537,17 @@ namespace Opus
// aapt resource value: 0x7f0b01a7
public const int headerAuthor = 2131427751;
// aapt resource value: 0x7f0b01ab
public const int headerMore = 2131427755;
// aapt resource value: 0x7f0b01ac
public const int headerMore = 2131427756;
// aapt resource value: 0x7f0b01a8
public const int headerNumber = 2131427752;
// aapt resource value: 0x7f0b01a9
public const int headerPlay = 2131427753;
// aapt resource value: 0x7f0b01aa
public const int headerShuffle = 2131427754;
public const int headerPlay = 2131427754;
// aapt resource value: 0x7f0b01ab
public const int headerShuffle = 2131427755;
// aapt resource value: 0x7f0b01a6
public const int headerTitle = 2131427750;
@@ -5561,8 +5561,8 @@ namespace Opus
// aapt resource value: 0x7f0b00a2
public const int icon = 2131427490;
// aapt resource value: 0x7f0b01c8
public const int icon1 = 2131427784;
// aapt resource value: 0x7f0b01c9
public const int icon1 = 2131427785;
// aapt resource value: 0x7f0b0128
public const int icon_frame = 2131427624;
@@ -5588,8 +5588,8 @@ namespace Opus
// aapt resource value: 0x7f0b01a4
public const int infoPanel = 2131427748;
// aapt resource value: 0x7f0b01ba
public const int isLive = 2131427770;
// aapt resource value: 0x7f0b01bb
public const int isLive = 2131427771;
// aapt resource value: 0x7f0b0092
public const int italic = 2131427474;
@@ -5618,8 +5618,8 @@ namespace Opus
// aapt resource value: 0x7f0b0029
public const int line1 = 2131427369;
// aapt resource value: 0x7f0b01cb
public const int line2 = 2131427787;
// aapt resource value: 0x7f0b01cc
public const int line2 = 2131427788;
// aapt resource value: 0x7f0b002a
public const int line3 = 2131427370;
@@ -5654,17 +5654,17 @@ namespace Opus
// aapt resource value: 0x7f0b0102
public const int logo = 2131427586;
// aapt resource value: 0x7f0b01cd
public const int masked = 2131427789;
// aapt resource value: 0x7f0b01ce
public const int masked = 2131427790;
// aapt resource value: 0x7f0b01c6
public const int maxValue = 2131427782;
// aapt resource value: 0x7f0b01c7
public const int maxValue = 2131427783;
// aapt resource value: 0x7f0b0181
public const int media_actions = 2131427713;
// aapt resource value: 0x7f0b01d7
public const int media_route_menu_item = 2131427799;
// aapt resource value: 0x7f0b01d8
public const int media_route_menu_item = 2131427800;
// aapt resource value: 0x7f0b00cd
public const int message = 2131427533;
@@ -5693,8 +5693,8 @@ namespace Opus
// aapt resource value: 0x7f0b0063
public const int middle = 2131427427;
// aapt resource value: 0x7f0b01c5
public const int minValue = 2131427781;
// aapt resource value: 0x7f0b01c6
public const int minValue = 2131427782;
// aapt resource value: 0x7f0b0083
public const int mini = 2131427459;
@@ -5861,8 +5861,8 @@ namespace Opus
// aapt resource value: 0x7f0b005a
public const int multiply = 2131427418;
// aapt resource value: 0x7f0b01ce
public const int musicLayout = 2131427790;
// aapt resource value: 0x7f0b01cf
public const int musicLayout = 2131427791;
// aapt resource value: 0x7f0b0101
public const int name = 2131427585;
@@ -5903,8 +5903,8 @@ namespace Opus
// aapt resource value: 0x7f0b008a
public const int outline = 2131427466;
// aapt resource value: 0x7f0b01ca
public const int pager = 2131427786;
// aapt resource value: 0x7f0b01cb
public const int pager = 2131427787;
// aapt resource value: 0x7f0b0081
public const int parallax = 2131427457;
@@ -5948,11 +5948,14 @@ namespace Opus
// aapt resource value: 0x7f0b013c
public const int playersHolder = 2131427644;
// aapt resource value: 0x7f0b01a9
public const int playlistButtons = 2131427753;
// aapt resource value: 0x7f0b0134
public const int playlistHeader = 2131427636;
// aapt resource value: 0x7f0b01d0
public const int playlistLayout = 2131427792;
// aapt resource value: 0x7f0b01d1
public const int playlistLayout = 2131427793;
// aapt resource value: 0x7f0b010a
public const int playlistLocation = 2131427594;
@@ -5960,8 +5963,8 @@ namespace Opus
// aapt resource value: 0x7f0b0109
public const int playlistName = 2131427593;
// aapt resource value: 0x7f0b01c2
public const int playlistURL = 2131427778;
// aapt resource value: 0x7f0b01c3
public const int playlistURL = 2131427779;
// aapt resource value: 0x7f0b011a
public const int progress = 2131427610;
@@ -5987,8 +5990,8 @@ namespace Opus
// aapt resource value: 0x7f0b01a1
public const int queueParent = 2131427745;
// aapt resource value: 0x7f0b01bd
public const int queueSwitch = 2131427773;
// aapt resource value: 0x7f0b01be
public const int queueSwitch = 2131427774;
// aapt resource value: 0x7f0b00b8
public const int radio = 2131427512;
@@ -5996,14 +5999,14 @@ namespace Opus
// aapt resource value: 0x7f0b00d1
public const int recycler = 2131427537;
// aapt resource value: 0x7f0b01b1
public const int recycler_view = 2131427761;
// aapt resource value: 0x7f0b01b2
public const int recycler_view = 2131427762;
// aapt resource value: 0x7f0b01c9
public const int refine = 2131427785;
// aapt resource value: 0x7f0b01ca
public const int refine = 2131427786;
// aapt resource value: 0x7f0b01c7
public const int reorder = 2131427783;
// aapt resource value: 0x7f0b01c8
public const int reorder = 2131427784;
// aapt resource value: 0x7f0b0197
public const int repeat = 2131427735;
@@ -6014,8 +6017,8 @@ namespace Opus
// aapt resource value: 0x7f0b012f
public const int rightButtons = 2131427631;
// aapt resource value: 0x7f0b01c0
public const int rightIcon = 2131427776;
// aapt resource value: 0x7f0b01c1
public const int rightIcon = 2131427777;
// aapt resource value: 0x7f0b0189
public const int right_icon = 2131427721;
@@ -6023,8 +6026,8 @@ namespace Opus
// aapt resource value: 0x7f0b0185
public const int right_side = 2131427717;
// aapt resource value: 0x7f0b01d5
public const int saveAsPlaylist = 2131427797;
// aapt resource value: 0x7f0b01d6
public const int saveAsPlaylist = 2131427798;
// aapt resource value: 0x7f0b0019
public const int save_image_matrix = 2131427353;
@@ -6053,11 +6056,11 @@ namespace Opus
// aapt resource value: 0x7f0b0087
public const int scrollable = 2131427463;
// aapt resource value: 0x7f0b01c3
public const int search = 2131427779;
// aapt resource value: 0x7f0b01c4
public const int searchSuggestions = 2131427780;
public const int search = 2131427780;
// aapt resource value: 0x7f0b01c5
public const int searchSuggestions = 2131427781;
// aapt resource value: 0x7f0b00c2
public const int search_badge = 2131427522;
@@ -6095,11 +6098,11 @@ namespace Opus
// aapt resource value: 0x7f0b00e8
public const int seek_bar_controls = 2131427560;
// aapt resource value: 0x7f0b01b2
public const int seekbar = 2131427762;
// aapt resource value: 0x7f0b01b3
public const int seekbar_value = 2131427763;
public const int seekbar = 2131427763;
// aapt resource value: 0x7f0b01b4
public const int seekbar_value = 2131427764;
// aapt resource value: 0x7f0b00cc
public const int select_dialog_listview = 2131427532;
@@ -6107,8 +6110,8 @@ namespace Opus
// aapt resource value: 0x7f0b0079
public const int selected = 2131427449;
// aapt resource value: 0x7f0b01d8
public const int settings = 2131427800;
// aapt resource value: 0x7f0b01d9
public const int settings = 2131427801;
// aapt resource value: 0x7f0b00b4
public const int shortcut = 2131427508;
@@ -6152,8 +6155,8 @@ namespace Opus
// aapt resource value: 0x7f0b019c
public const int songTimer = 2131427740;
// aapt resource value: 0x7f0b01b9
public const int songView = 2131427769;
// aapt resource value: 0x7f0b01ba
public const int songView = 2131427770;
// aapt resource value: 0x7f0b0140
public const int spArt = 2131427648;
@@ -6188,8 +6191,8 @@ namespace Opus
// aapt resource value: 0x7f0b00a4
public const int spacer = 2131427492;
// aapt resource value: 0x7f0b01b0
public const int spinner = 2131427760;
// aapt resource value: 0x7f0b01b1
public const int spinner = 2131427761;
// aapt resource value: 0x7f0b0015
public const int split_action_bar = 2131427349;
@@ -6236,11 +6239,11 @@ namespace Opus
// aapt resource value: 0x7f0b0098
public const int surface_view = 2131427480;
// aapt resource value: 0x7f0b01b4
public const int switchWidget = 2131427764;
// aapt resource value: 0x7f0b01b5
public const int switchWidget = 2131427765;
// aapt resource value: 0x7f0b01af
public const int sync = 2131427759;
// aapt resource value: 0x7f0b01b0
public const int sync = 2131427760;
// aapt resource value: 0x7f0b00d0
public const int syncLoading = 2131427536;
@@ -6272,8 +6275,8 @@ namespace Opus
// aapt resource value: 0x7f0b002f
public const int text2 = 2131427375;
// aapt resource value: 0x7f0b01ac
public const int textLayout = 2131427756;
// aapt resource value: 0x7f0b01ad
public const int textLayout = 2131427757;
// aapt resource value: 0x7f0b00aa
public const int textSpacerNoButtons = 2131427498;
@@ -6332,8 +6335,8 @@ namespace Opus
// aapt resource value: 0x7f0b0070
public const int top = 2131427440;
// aapt resource value: 0x7f0b01b8
public const int topDivider = 2131427768;
// aapt resource value: 0x7f0b01b9
public const int topDivider = 2131427769;
// aapt resource value: 0x7f0b00ae
public const int topPanel = 2131427502;
@@ -6356,8 +6359,8 @@ namespace Opus
// aapt resource value: 0x7f0b0020
public const int transition_transform = 2131427360;
// aapt resource value: 0x7f0b01d3
public const int undoChange = 2131427795;
// aapt resource value: 0x7f0b01d4
public const int undoChange = 2131427796;
// aapt resource value: 0x7f0b005f
public const int uniform = 2131427423;
@@ -6377,8 +6380,8 @@ namespace Opus
// aapt resource value: 0x7f0b0028
public const int view_offset_helper = 2131427368;
// aapt resource value: 0x7f0b01cc
public const int visible = 2131427788;
// aapt resource value: 0x7f0b01cd
public const int visible = 2131427789;
// aapt resource value: 0x7f0b016c
public const int volume_item_container = 2131427692;
@@ -6392,8 +6395,8 @@ namespace Opus
// aapt resource value: 0x7f0b0060
public const int wrap_content = 2131427424;
// aapt resource value: 0x7f0b01bb
public const int youtubeIcon = 2131427771;
// aapt resource value: 0x7f0b01bc
public const int youtubeIcon = 2131427772;
// aapt resource value: 0x7f0b0137
public const int ytProgress = 2131427639;

View File

@@ -56,6 +56,7 @@
android:layout_width="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:id="@+id/playlistButtons"
android:background="@drawable/semiDarkLinear" >
<ImageButton
android:id="@+id/headerPlay"