From 13cb0934a5ba59cd352a6400a17dcde31155d399 Mon Sep 17 00:00:00 2001
From: Tristan Roux
Date: Sat, 20 Apr 2019 01:31:16 +0200
Subject: [PATCH] Starting to rework code oraganizing structure. Making browse
use content loader and load only what it need.
---
Opus/Code/Adapter/BaseCursor.cs | 77 ++++++++
Opus/Code/Adapter/BrowseAdapter.cs | 115 ++++++++++++
Opus/Code/DataStructure/Song.cs | 138 ++++++++++++++
.../DataStructure}/UslessHolder.cs | 2 +-
.../Fragments}/Browse.cs | 175 +++++++----------
Opus/{ => Code}/MainActivity.cs | 2 +
Opus/Opus.csproj | 15 +-
.../Portable Class/AddToPlaylistAdapter.cs | 1 +
.../Resources/Portable Class/BrowseAdapter.cs | 109 -----------
.../Portable Class/CastQueueManager.cs | 1 +
.../Portable Class/CurrentItemDecoration.cs | 7 +-
Opus/Resources/Portable Class/Downloader.cs | 1 +
Opus/Resources/Portable Class/EditMetaData.cs | 1 +
Opus/Resources/Portable Class/FolderBrowse.cs | 2 +
Opus/Resources/Portable Class/FolderTracks.cs | 177 +++++++++---------
Opus/Resources/Portable Class/Home.cs | 1 +
Opus/Resources/Portable Class/HomeAdapter.cs | 1 +
.../Portable Class/HomeListAdapter.cs | 7 +-
Opus/Resources/Portable Class/HomeSection.cs | 1 +
Opus/Resources/Portable Class/LineAdapter.cs | 10 +-
Opus/Resources/Portable Class/MusicPlayer.cs | 2 +
.../Resources/Portable Class/PagerFragment.cs | 1 +
Opus/Resources/Portable Class/Player.cs | 6 +-
Opus/Resources/Portable Class/Playlist.cs | 2 +
.../Portable Class/PlaylistAdapter.cs | 1 +
Opus/Resources/Portable Class/PlaylistItem.cs | 3 +-
.../Portable Class/PlaylistTrackAdapter.cs | 5 +-
.../Portable Class/PlaylistTracks.cs | 2 +
Opus/Resources/Portable Class/Queue.cs | 4 +-
Opus/Resources/Portable Class/QueueAdapter.cs | 7 +-
.../Portable Class/RecyclerHolder.cs | 41 ----
.../Portable Class/SnackbarCallback.cs | 1 +
Opus/Resources/Portable Class/Song.cs | 74 --------
.../Resources/Portable Class/YoutubeEngine.cs | 2 +
Opus/Resources/Portable Class/YtAdapter.cs | 5 +-
Opus/Resources/Portable Class/YtFile.cs | 3 +-
36 files changed, 558 insertions(+), 444 deletions(-)
create mode 100644 Opus/Code/Adapter/BaseCursor.cs
create mode 100644 Opus/Code/Adapter/BrowseAdapter.cs
create mode 100644 Opus/Code/DataStructure/Song.cs
rename Opus/{Resources/Portable Class => Code/DataStructure}/UslessHolder.cs (90%)
rename Opus/{Resources/Portable Class => Code/Fragments}/Browse.cs (88%)
rename Opus/{ => Code}/MainActivity.cs (99%)
delete mode 100644 Opus/Resources/Portable Class/BrowseAdapter.cs
delete mode 100644 Opus/Resources/Portable Class/RecyclerHolder.cs
delete mode 100644 Opus/Resources/Portable Class/Song.cs
diff --git a/Opus/Code/Adapter/BaseCursor.cs b/Opus/Code/Adapter/BaseCursor.cs
new file mode 100644
index 0000000..e1b3b06
--- /dev/null
+++ b/Opus/Code/Adapter/BaseCursor.cs
@@ -0,0 +1,77 @@
+using Android.Database;
+using Android.Support.V7.Widget;
+using Android.Views;
+
+namespace Opus.Adapter
+{
+ public abstract class BaseCursor : RecyclerView.Adapter
+ {
+ public ICursor cursor;
+ ///
+ /// This is the number of items (for example headers) there is before the list represented by the cursor.
+ ///
+ public abstract int ItemBefore { get; }
+ public int BaseCount { get { return cursor != null ? cursor.Count : 0; } }
+ public override int ItemCount => BaseCount + ItemBefore;
+
+ public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
+ {
+ if (cursor.MoveToPosition(position - ItemBefore))
+ OnBindViewHolder(holder, Convert(cursor));
+ }
+ public abstract void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, T item);
+
+ public void SwapCursor(ICursor newCursor)
+ {
+ if (newCursor == cursor)
+ return;
+
+ if (newCursor != null)
+ {
+ MainActivity.instance.FindViewById(Resource.Id.loading).Visibility = ViewStates.Gone;
+ cursor = newCursor;
+ NotifyDataSetChanged();
+ }
+ else
+ {
+ NotifyItemRangeRemoved(0, ItemCount);
+ cursor = null;
+ MainActivity.instance.FindViewById(Resource.Id.loading).Visibility = ViewStates.Visible;
+ }
+ }
+
+ public T GetItem(int position)
+ {
+ cursor.MoveToPosition(position - ItemBefore);
+ return Convert(cursor);
+ }
+
+ public void OnClick(int position)
+ {
+ if (position >= ItemBefore)
+ {
+ cursor.MoveToPosition(position - ItemBefore);
+ Clicked(Convert(cursor));
+ }
+ else
+ HeaderClicked(position);
+ }
+ public abstract void Clicked(T item);
+ public virtual void HeaderClicked(int position) { }
+
+ public void OnLongClick(int position)
+ {
+ if (position >= ItemBefore)
+ {
+ cursor.MoveToPosition(position - ItemBefore);
+ LongClicked(Convert(cursor));
+ }
+ else
+ HeaderLongClicked(position);
+ }
+ public abstract void LongClicked(T item);
+ public virtual void HeaderLongClicked(int position) { }
+
+ public abstract T Convert(ICursor cursor);
+ }
+}
\ No newline at end of file
diff --git a/Opus/Code/Adapter/BrowseAdapter.cs b/Opus/Code/Adapter/BrowseAdapter.cs
new file mode 100644
index 0000000..624ebfc
--- /dev/null
+++ b/Opus/Code/Adapter/BrowseAdapter.cs
@@ -0,0 +1,115 @@
+using Android.App;
+using Android.Content;
+using Android.Database;
+using Android.Graphics;
+using Android.Support.V7.Widget;
+using Android.Views;
+using Opus.DataStructure;
+using Opus.Fragments;
+using Square.Picasso;
+
+namespace Opus.Adapter
+{
+ public class BrowseAdapter : BaseCursor
+ {
+ public bool displayShuffle;
+ public override int ItemBefore => (displayShuffle && BaseCount != 0) ? 1 : 0;
+
+
+ public BrowseAdapter()
+ {
+ cursor = null;
+ displayShuffle = true;
+ }
+
+ public BrowseAdapter(ICursor cursor, bool displayShuffle)
+ {
+ this.cursor = cursor;
+ this.displayShuffle = displayShuffle;
+ }
+
+ public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
+ {
+ if (position == 0 && displayShuffle)
+ {
+ if (MainActivity.Theme == 1)
+ ((CardView)viewHolder.ItemView).SetCardBackgroundColor(Color.ParseColor("#212121"));
+ else
+ ((CardView)viewHolder.ItemView).SetCardBackgroundColor(Color.White);
+ }
+ else
+ base.OnBindViewHolder(viewHolder, position);
+ }
+
+ public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, Song song)
+ {
+ SongHolder holder = (SongHolder)viewHolder;
+
+ if (MainActivity.Theme == 1)
+ {
+ holder.more.SetColorFilter(Color.White);
+ holder.Title.SetTextColor(Color.White);
+ holder.Artist.SetTextColor(Color.White);
+ holder.Artist.Alpha = 0.7f;
+ }
+
+ holder.Title.Text = song.Title;
+ holder.Artist.Text = song.Artist;
+
+ var songCover = Android.Net.Uri.Parse("content://media/external/audio/albumart");
+ var songAlbumArtUri = ContentUris.WithAppendedId(songCover, song.AlbumArt);
+ Picasso.With(Application.Context).Load(songAlbumArtUri).Placeholder(Resource.Color.background_material_dark).Resize(400, 400).CenterCrop().Into(holder.AlbumArt);
+
+ if (!holder.more.HasOnClickListeners)
+ {
+ holder.more.Click += (sender, e) =>
+ {
+ Browse.instance?.More(GetItem(holder.AdapterPosition));
+ };
+ }
+ }
+
+ public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
+ {
+ if (viewType == 0)
+ {
+ View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.ShuffleButton, parent, false);
+ return new UslessHolder(itemView, OnClick);
+ }
+ else
+ {
+ View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.SongList, parent, false);
+ return new SongHolder(itemView, OnClick, OnLongClick);
+ }
+ }
+
+ public override int GetItemViewType(int position)
+ {
+ if (position == 0 && displayShuffle)
+ return 0;
+ else
+ return 1;
+ }
+
+ public override void HeaderClicked(int position)
+ {
+ MainActivity.instance.ShuffleAll();
+ }
+
+ public override void Clicked(Song song)
+ {
+ song = Browse.CompleteItem(song);
+ Browse.Play(song);
+ }
+
+ public override void LongClicked(Song song)
+ {
+ Browse.instance?.More(song);
+ }
+
+ public override Song Convert(ICursor cursor)
+ {
+ return Song.FromCursor(cursor);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Opus/Code/DataStructure/Song.cs b/Opus/Code/DataStructure/Song.cs
new file mode 100644
index 0000000..ab200d0
--- /dev/null
+++ b/Opus/Code/DataStructure/Song.cs
@@ -0,0 +1,138 @@
+using Android.Database;
+using Android.Gms.Cast;
+using Android.Provider;
+using Android.Support.V7.Widget;
+using Android.Views;
+using Android.Widget;
+using Newtonsoft.Json;
+using SQLite;
+using System;
+
+namespace Opus.DataStructure
+{
+ [Serializable]
+ public class Song
+ {
+ [PrimaryKey, Unique]
+ public int Index { get; set; }
+
+ public string Title { get; set; }
+ public string Artist { get; set; }
+ public string Album { get; set; }
+ public long AlbumArt { get; set; }
+ public string YoutubeID { get; set; }
+ public long Id { get; set; }
+ public string Path { get; set; }
+ public bool? IsParsed { get; set; }
+ public bool IsYt { get; set; }
+ public DateTimeOffset? ExpireDate { get; set;}
+ public bool IsLiveStream = false;
+ public string TrackID;
+
+ public Song() { }
+
+ public Song(string title, string artist, string album, string youtubeID, long albumArt, long id, string path, bool isYT = false, bool isParsed = true)
+ {
+ Title = title;
+ Artist = artist;
+ Album = album;
+ YoutubeID = youtubeID;
+ AlbumArt = albumArt;
+ Id = id;
+ Path = path;
+ IsYt = isYT;
+ IsParsed = isParsed;
+ }
+
+ public override string ToString()
+ {
+ return Title + " Artist: " + Artist + " Album: " + Album + " youtubeID: " + YoutubeID + " AlbumArt: " + AlbumArt + " Id: " + Id + " Path: " + Path + " isYT: " + IsYt + " isParsed: " + IsParsed;
+ }
+
+ public static Song FromCursor(ICursor cursor)
+ {
+ int titleID = cursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Title);
+ int artistID = cursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Artist);
+ int albumID = cursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Album);
+ int thisID = cursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Id);
+ int pathID = cursor.GetColumnIndex(MediaStore.Audio.Media.InterfaceConsts.Data);
+
+ string Artist = cursor.GetString(artistID);
+ string Title = cursor.GetString(titleID);
+ string Album = cursor.GetString(albumID);
+ long AlbumArt = cursor.GetLong(cursor.GetColumnIndex(MediaStore.Audio.Albums.InterfaceConsts.AlbumId));
+ long id = cursor.GetLong(thisID);
+ string path = cursor.GetString(pathID);
+
+ if (Title == null)
+ Title = "Unknown Title";
+ if (Artist == null)
+ Artist = "Unknow Artist";
+ if (Album == null)
+ Album = "Unknow Album";
+
+ return new Song(Title, Artist, Album, null, AlbumArt, id, path);
+ }
+
+
+ public static explicit operator Song(string v)
+ {
+ if (v == null)
+ return null;
+
+ string Name = v.Substring(0, v.IndexOf(" Artist: "));
+ string Artist = v.Substring(v.IndexOf(" Artist: ") + 9, v.IndexOf(" Album: ") - Name.Length - 8);
+ string Album = v.Substring(v.IndexOf(" Album: ") + 8, v.IndexOf(" youtubeID: ") - v.IndexOf(" Album: ") - 8);
+ string youtubeID = v.Substring(v.IndexOf(" youtubeID: ") + 12, v.IndexOf(" AlbumArt: ") - v.IndexOf(" youtubeID: ") - 12);
+ long AlbumArt = long.Parse(v.Substring(v.IndexOf(" AlbumArt: ") + 11, v.IndexOf(" Id: ") - v.IndexOf(" AlbumArt: ") - 11));
+ long id = long.Parse(v.Substring(v.IndexOf(" Id: ") + 5, v.IndexOf(" Path: ") - v.IndexOf(" Id: ") - 5));
+ string path = v.Substring(v.IndexOf(" Path: ") + 7, v.IndexOf(" isYT: ") - v.IndexOf(" Path: ") - 7);
+ bool isYT = bool.Parse(v.Substring(v.IndexOf(" isYT: ") + 7, v.IndexOf(" isParsed: ") - v.IndexOf(" isYT: ") - 7));
+ bool isParsed = bool.Parse(v.Substring(v.IndexOf(" isParsed: ") + 11));
+
+ Song song = new Song(Name, Artist, Album, youtubeID, AlbumArt, id, path, isYT, isParsed);
+ return song;
+ }
+
+ public static explicit operator Song(MediaQueueItem v)
+ {
+ if (v == null)
+ return null;
+
+ return JsonConvert.DeserializeObject(v.Media.CustomData.ToString());
+ }
+ }
+
+ public class SongHolder : RecyclerView.ViewHolder
+ {
+ public ImageView reorder;
+ public TextView Title;
+ public TextView Artist;
+ public TextView Live;
+ public ImageView AlbumArt;
+ public ImageView youtubeIcon;
+ public ImageView more;
+ public TextView status;
+ public Button action;
+ public View RightButtons;
+ public View TextLayout;
+
+ public SongHolder(View itemView, Action listener, Action longListener) : base(itemView)
+ {
+ reorder = itemView.FindViewById(Resource.Id.reorder);
+ Title = itemView.FindViewById(Resource.Id.title);
+ Artist = itemView.FindViewById(Resource.Id.artist);
+ Live = itemView.FindViewById(Resource.Id.isLive);
+ AlbumArt = itemView.FindViewById(Resource.Id.albumArt);
+ youtubeIcon = itemView.FindViewById(Resource.Id.youtubeIcon);
+ more = itemView.FindViewById(Resource.Id.moreButton);
+ RightButtons = itemView.FindViewById(Resource.Id.rightButtons);
+ TextLayout = itemView.FindViewById(Resource.Id.textLayout);
+ status = itemView.FindViewById(Resource.Id.status);
+ action = itemView.FindViewById