mirror of
https://github.com/zoriya/Opus.git
synced 2025-12-06 06:26:15 +00:00
Reworked add to playlist behaviors.
This commit is contained in:
@@ -32,6 +32,32 @@ namespace Opus.Api
|
||||
{
|
||||
public class PlaylistManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Return a complete PlaylistItem object from the youtube id of the playlist
|
||||
/// </summary>
|
||||
/// <param name="playlistID"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<PlaylistItem> GetPlaylist(string playlistID)
|
||||
{
|
||||
PlaylistsResource.ListRequest request = YoutubeManager.YoutubeService.Playlists.List("snippet");
|
||||
request.Id = playlistID;
|
||||
|
||||
PlaylistListResponse response = await request.ExecuteAsync();
|
||||
|
||||
if (response.Items.Count > 0)
|
||||
{
|
||||
Playlist result = response.Items[0];
|
||||
return new PlaylistItem(result.Snippet.Title, -1, playlistID)
|
||||
{
|
||||
HasWritePermission = false,
|
||||
ImageURL = result.Snippet.Thumbnails.High.Url,
|
||||
Owner = result.Snippet.ChannelTitle
|
||||
};
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
#region PlayInOrder
|
||||
/// <summary>
|
||||
/// Play all tracks of a playlist in the default order. Handle both youtube and local playlists.
|
||||
@@ -349,14 +375,22 @@ namespace Opus.Api
|
||||
holder.Status.SetImageResource(Resource.Drawable.Sync);
|
||||
});
|
||||
|
||||
foreach (PlaylistItem playlist in youtube)
|
||||
playlist.SongContained = await YoutubeManager.SongIsContained(item.YoutubeID, playlist.YoutubeID);
|
||||
if(youtube != null)
|
||||
{
|
||||
foreach (PlaylistItem playlist in youtube)
|
||||
playlist.SongContained = await YoutubeManager.SongIsContained(item.YoutubeID, playlist.YoutubeID);
|
||||
|
||||
int positionStart = playlists.IndexOf(Loading);
|
||||
playlists.Remove(Loading);
|
||||
playlists.AddRange(youtube);
|
||||
adapter.NotifyItemRangeInserted(positionStart, youtube.Count - 1);
|
||||
adapter.NotifyItemChanged(playlists.Count);
|
||||
int positionStart = playlists.IndexOf(Loading);
|
||||
playlists.Remove(Loading);
|
||||
playlists.AddRange(youtube);
|
||||
adapter.NotifyItemRangeInserted(positionStart, youtube.Count - 1);
|
||||
adapter.NotifyItemChanged(playlists.Count);
|
||||
}
|
||||
else
|
||||
{
|
||||
playlists.Remove(Loading);
|
||||
adapter.NotifyItemRemoved(playlists.Count);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -654,7 +688,7 @@ namespace Opus.Api
|
||||
/// <param name="SyncedPlaylists"></param>
|
||||
/// <param name="UiCallback">A callback that will tell the ui to update a synced playlist with the new data got from the item.</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<(List<PlaylistItem>, string)> GetOwnedYoutubePlaylists(List<PlaylistItem> SyncedPlaylists, System.Action<PlaylistItem, int> UiCallback)
|
||||
public static async Task<(List<PlaylistItem>, string)> GetOwnedYoutubePlaylists(List<PlaylistItem> SyncedPlaylists, Action<PlaylistItem, int> UiCallback)
|
||||
{
|
||||
if (!await MainActivity.instance.WaitForYoutube() || YoutubeManager.IsUsingAPI)
|
||||
return (null, "Error"); //Should have a better error handling
|
||||
@@ -699,51 +733,23 @@ namespace Opus.Api
|
||||
/// <param name="SyncedPlaylists"></param>
|
||||
/// <param name="UiCallback">A callback that will tell the ui to update a synced playlist with the new data got from the item.</param>
|
||||
/// <returns></returns>
|
||||
public static async Task<(List<PlaylistItem>, string)> GetSavedYoutubePlaylists(List<PlaylistItem> SyncedPlaylists, System.Action<PlaylistItem, int> UiCallback)
|
||||
public static async Task<List<PlaylistItem>> GetSavedYoutubePlaylists(List<PlaylistItem> SyncedPlaylists, Action<PlaylistItem, int> UiCallback)
|
||||
{
|
||||
if (!await MainActivity.instance.WaitForYoutube())
|
||||
return (null, "Error"); //Should have a better error handling
|
||||
List<PlaylistItem> SavedPlaylists = new List<PlaylistItem>();
|
||||
await Task.Run(() =>
|
||||
{
|
||||
SQLiteConnection db = new SQLiteConnection(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "SavedPlaylists.sqlite"));
|
||||
db.CreateTable<SavedPlaylist>();
|
||||
|
||||
SavedPlaylists = db.Table<SavedPlaylist>().ToList().ConvertAll(x => { PlaylistItem y = x; y.YoutubeID = x.YoutubeID; y.LocalID = -1; return y; });
|
||||
});
|
||||
|
||||
List<PlaylistItem> YoutubePlaylists = new List<PlaylistItem>();
|
||||
|
||||
try
|
||||
{
|
||||
YouTubeService youtube = YoutubeManager.YoutubeService;
|
||||
foreach (PlaylistItem item in SavedPlaylists)
|
||||
ProcessPlaylistSyncState(item, SyncedPlaylists, YoutubePlaylists, UiCallback);
|
||||
|
||||
ChannelSectionsResource.ListRequest forkedRequest = youtube.ChannelSections.List("snippet,contentDetails");
|
||||
forkedRequest.Mine = true;
|
||||
ChannelSectionListResponse forkedResponse = await forkedRequest.ExecuteAsync();
|
||||
|
||||
foreach (ChannelSection section in forkedResponse.Items)
|
||||
{
|
||||
if (section.Snippet.Title == "Saved Playlists")
|
||||
{
|
||||
for (int i = 0; i < section.ContentDetails.Playlists.Count; i++)
|
||||
{
|
||||
PlaylistsResource.ListRequest plRequest = youtube.Playlists.List("snippet, contentDetails");
|
||||
plRequest.Id = section.ContentDetails.Playlists[i];
|
||||
PlaylistListResponse plResponse = await plRequest.ExecuteAsync();
|
||||
|
||||
Playlist playlist = plResponse.Items[i];
|
||||
playlist.Kind = "youtube#saved";
|
||||
PlaylistItem item = new PlaylistItem(playlist.Snippet.Title, playlist.Id, playlist, (int)playlist.ContentDetails.ItemCount)
|
||||
{
|
||||
Owner = playlist.Snippet.ChannelTitle,
|
||||
ImageURL = playlist.Snippet.Thumbnails.High.Url,
|
||||
HasWritePermission = false
|
||||
};
|
||||
|
||||
ProcessPlaylistSyncState(item, SyncedPlaylists, YoutubePlaylists, UiCallback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (YoutubePlaylists, null);
|
||||
}
|
||||
catch (System.Net.Http.HttpRequestException)
|
||||
{
|
||||
return (null, "Error"); //Should handle precise error here
|
||||
}
|
||||
return YoutubePlaylists;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -753,7 +759,7 @@ namespace Opus.Api
|
||||
/// <param name="SyncedPlaylists">An array of known synced playlists (Will be updated)</param>
|
||||
/// <param name="YoutubePlaylists">An array of youtube playlists. (Will be updated)</param>
|
||||
/// <param name="UiCallback">A callback that will tell the ui to update a synced playlist with the new data got from the item.</param>
|
||||
public static void ProcessPlaylistSyncState(PlaylistItem item, List<PlaylistItem> SyncedPlaylists, List<PlaylistItem> YoutubePlaylists, System.Action<PlaylistItem, int> UiCallback)
|
||||
public static void ProcessPlaylistSyncState(PlaylistItem item, List<PlaylistItem> SyncedPlaylists, List<PlaylistItem> YoutubePlaylists, Action<PlaylistItem, int> UiCallback)
|
||||
{
|
||||
PlaylistItem syncedItem = SyncedPlaylists?.Find(x => x.YoutubeID == item.YoutubeID);
|
||||
if (syncedItem != null)
|
||||
@@ -1080,111 +1086,58 @@ namespace Opus.Api
|
||||
}
|
||||
#endregion
|
||||
|
||||
//Not handled yet
|
||||
#region YoutubeFork
|
||||
/// <summary>
|
||||
/// Fork playlist (not implemeted yet)
|
||||
/// Return true if the playlist is already forked.
|
||||
/// </summary>
|
||||
/// <param name="playlistID"></param>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public static /*async*/ void ForkPlaylist(string playlistID)
|
||||
public async static Task<bool> IsForked(PlaylistItem item)
|
||||
{
|
||||
//ChannelSectionsResource.ListRequest forkedRequest = youtubeService.ChannelSections.List("snippet,contentDetails");
|
||||
//forkedRequest.Mine = true;
|
||||
//ChannelSectionListResponse forkedResponse = await forkedRequest.ExecuteAsync();
|
||||
|
||||
//foreach (ChannelSection section in forkedResponse.Items)
|
||||
//{
|
||||
// if (section.Snippet.Title == "Saved Playlists")
|
||||
// {
|
||||
// //AddToSection
|
||||
// if (section.ContentDetails.Playlists.Contains(playlistID))
|
||||
// {
|
||||
// Snackbar snackBar = Snackbar.Make(MainActivity.instance.FindViewById<CoordinatorLayout>(Resource.Id.snackBar), Resource.String.playlist_already_saved, Snackbar.LengthLong);
|
||||
// snackBar.View.FindViewById<TextView>(Resource.Id.snackbar_text).SetTextColor(Color.White);
|
||||
// snackBar.Show();
|
||||
// return;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// section.ContentDetails.Playlists.Add(playlistID);
|
||||
// ChannelSectionsResource.UpdateRequest request = youtubeService.ChannelSections.Update(section, "snippet,contentDetails");
|
||||
// ChannelSection response = await request.ExecuteAsync();
|
||||
// }
|
||||
// catch (System.Net.Http.HttpRequestException)
|
||||
// {
|
||||
// MainActivity.instance.Timout();
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
////CreateSection and add to it
|
||||
//ChannelSection newSection = new ChannelSection();
|
||||
//ChannelSectionContentDetails details = new ChannelSectionContentDetails();
|
||||
//ChannelSectionSnippet snippet = new ChannelSectionSnippet();
|
||||
|
||||
//details.Playlists = new List<string>() { playlistID };
|
||||
//snippet.Title = "Saved Playlists";
|
||||
//snippet.Type = "multiplePlaylists";
|
||||
//snippet.Style = "horizontalRow";
|
||||
|
||||
//newSection.ContentDetails = details;
|
||||
//newSection.Snippet = snippet;
|
||||
|
||||
//ChannelSectionsResource.InsertRequest insert = youtubeService.ChannelSections.Insert(newSection, "snippet,contentDetails");
|
||||
//ChannelSection insertResponse = await insert.ExecuteAsync();
|
||||
List<PlaylistItem> SavedPlaylistt = await GetSavedYoutubePlaylists(null, null);
|
||||
if (SavedPlaylistt.Count(x => x.YoutubeID == item.YoutubeID) > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void Unfork(int position, string playlistID)
|
||||
/// <summary>
|
||||
/// Save a playlist in the user library.
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <returns></returns>
|
||||
public static async void ForkPlaylist(PlaylistItem item)
|
||||
{
|
||||
//AlertDialog dialog = new AlertDialog.Builder(MainActivity.instance, MainActivity.dialogTheme)
|
||||
// .SetTitle(GetString(Resource.String.unfork_playlist, YoutubePlaylists[position - LocalPlaylists.Count].Name))
|
||||
// .SetPositiveButton(Resource.String.yes, async (sender, e) =>
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// ChannelSectionsResource.ListRequest forkedRequest = YoutubeEngine.youtubeService.ChannelSections.List("snippet,contentDetails");
|
||||
// forkedRequest.Mine = true;
|
||||
// ChannelSectionListResponse forkedResponse = await forkedRequest.ExecuteAsync();
|
||||
SavedPlaylist pl = new SavedPlaylist(item);
|
||||
await Task.Run(() =>
|
||||
{
|
||||
SQLiteConnection db = new SQLiteConnection(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "SavedPlaylists.sqlite"));
|
||||
db.CreateTable<SavedPlaylist>();
|
||||
db.InsertOrReplace(pl);
|
||||
});
|
||||
|
||||
// foreach (ChannelSection section in forkedResponse.Items)
|
||||
// {
|
||||
// if (section.Snippet.Title == "Saved Playlists")
|
||||
// {
|
||||
// if (section.ContentDetails.Playlists.Count > 1)
|
||||
// {
|
||||
// section.ContentDetails.Playlists.Remove(playlistID);
|
||||
// ChannelSectionsResource.UpdateRequest request = YoutubeEngine.youtubeService.ChannelSections.Update(section, "snippet,contentDetails");
|
||||
// ChannelSection response = await request.ExecuteAsync();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ChannelSectionsResource.DeleteRequest delete = YoutubeEngine.youtubeService.ChannelSections.Delete(section.Id);
|
||||
// await delete.ExecuteAsync();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
Snackbar snackBar = Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), MainActivity.instance.GetString(Resource.String.playlist_saved), Snackbar.LengthLong);
|
||||
snackBar.View.FindViewById<TextView>(Resource.Id.snackbar_text).SetTextColor(Color.White);
|
||||
snackBar.Show();
|
||||
}
|
||||
|
||||
// YoutubePlaylists.RemoveAt(position - LocalPlaylists.Count - 1);
|
||||
// adapter.NotifyItemRemoved(position);
|
||||
/// <summary>
|
||||
/// Remove a playlist from the user library.
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
public static async void Unfork(PlaylistItem item)
|
||||
{
|
||||
SavedPlaylist pl = new SavedPlaylist(item);
|
||||
await Task.Run(() =>
|
||||
{
|
||||
SQLiteConnection db = new SQLiteConnection(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "SavedPlaylists.sqlite"));
|
||||
db.CreateTable<SavedPlaylist>();
|
||||
db.Delete(pl);
|
||||
});
|
||||
|
||||
// if (YoutubePlaylists.Count == 1)
|
||||
// {
|
||||
// YoutubePlaylists.Add(new PlaylistItem("EMPTY", null) { Owner = Resources.GetString(Resource.String.youtube_playlist_empty) });
|
||||
// adapter.NotifyItemInserted(LocalPlaylists.Count + YoutubePlaylists.Count);
|
||||
// }
|
||||
// }
|
||||
// catch (System.Net.Http.HttpRequestException)
|
||||
// {
|
||||
// MainActivity.instance.Timout();
|
||||
// }
|
||||
// })
|
||||
// .SetNegativeButton(Resource.String.no, (sender, e) => { })
|
||||
// .Create();
|
||||
//dialog.Show();
|
||||
Snackbar snackBar = Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), MainActivity.instance.GetString(Resource.String.playlist_unsaved), Snackbar.LengthLong);
|
||||
snackBar.View.FindViewById<TextView>(Resource.Id.snackbar_text).SetTextColor(Color.White);
|
||||
snackBar.Show();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -6,6 +6,29 @@ using System;
|
||||
|
||||
namespace Opus.DataStructure
|
||||
{
|
||||
[Serializable]
|
||||
public class SavedPlaylist : PlaylistItem
|
||||
{
|
||||
[PrimaryKey, Unique]
|
||||
public new string YoutubeID { get; set; }
|
||||
public new long LocalID { get; set; }
|
||||
|
||||
public SavedPlaylist() { }
|
||||
|
||||
public SavedPlaylist(PlaylistItem item)
|
||||
{
|
||||
Name = item.Name;
|
||||
LocalID = item.LocalID;
|
||||
YoutubeID = item.YoutubeID;
|
||||
Count = item.Count;
|
||||
Snippet = item.Snippet;
|
||||
Owner = item.Owner;
|
||||
ImageURL = item.ImageURL;
|
||||
HasWritePermission = item.HasWritePermission;
|
||||
SyncState = item.SyncState;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class PlaylistItem
|
||||
{
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace Opus.Adapter
|
||||
{
|
||||
MainActivity.instance.contentRefresh.Refresh -= Home.instance.OnRefresh;
|
||||
Home.instance = null;
|
||||
MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(playlists[position], false)).AddToBackStack("Playlist Track").Commit();
|
||||
MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(playlists[position])).AddToBackStack("Playlist Track").Commit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,16 +29,6 @@ namespace Opus.Adapter
|
||||
this.YoutubePlaylists = YoutubePlaylists;
|
||||
}
|
||||
|
||||
public void UpdateElement(int position, PlaylistItem newPlaylist)
|
||||
{
|
||||
if(position < LocalPlaylists.Count)
|
||||
LocalPlaylists[position] = newPlaylist;
|
||||
else
|
||||
YoutubePlaylists[position] = newPlaylist;
|
||||
|
||||
NotifyItemChanged(position);
|
||||
}
|
||||
|
||||
public override int ItemCount => LocalPlaylists.Count + YoutubePlaylists.Count + (forkSaved ? 1 : 0);
|
||||
|
||||
public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
|
||||
@@ -126,8 +116,23 @@ namespace Opus.Adapter
|
||||
PlaylistItem playlist = YoutubePlaylists[position - LocalPlaylists.Count];
|
||||
|
||||
holder.Title.Text = playlist.Name;
|
||||
holder.Owner.Text = playlist.Owner;
|
||||
Picasso.With(Application.Context).Load(playlist.ImageURL).Placeholder(Resource.Color.background_material_dark).Transform(new RemoveBlackBorder(true)).Into(holder.AlbumArt);
|
||||
Picasso.With(Application.Context).Load(playlist.ImageURL).Placeholder(Resource.Color.placeholder).Transform(new RemoveBlackBorder(true)).Into(holder.AlbumArt);
|
||||
|
||||
if (playlist.Owner == null)
|
||||
{
|
||||
holder.Owner.Text = " ";
|
||||
holder.Owner.SetTextColor(Color.Transparent);
|
||||
holder.Owner.SetBackgroundResource(Resource.Color.placeholder);
|
||||
}
|
||||
else
|
||||
{
|
||||
holder.Owner.Text = playlist.Owner;
|
||||
holder.Owner.SetBackgroundColor(Color.Transparent);
|
||||
if (MainActivity.Theme == 1)
|
||||
holder.Owner.SetTextColor(Color.White);
|
||||
else
|
||||
holder.Owner.SetTextColor(Color.Black);
|
||||
}
|
||||
|
||||
if (playlist.HasWritePermission)
|
||||
{
|
||||
|
||||
@@ -53,11 +53,6 @@ namespace Opus.Adapter
|
||||
|
||||
public override void OnBindViewHolder(RecyclerView.ViewHolder viewHolder, int position)
|
||||
{
|
||||
System.Console.WriteLine("&Binding at " + position);
|
||||
System.Console.WriteLine("&ItemCount " + ItemCount);
|
||||
System.Console.WriteLine("&ItemBefore " + ItemBefore);
|
||||
System.Console.WriteLine("&ItemAfter " + ItemAfter);
|
||||
|
||||
if (position == ItemCount - 1 && !PlaylistTracks.instance.fullyLoadded)
|
||||
{
|
||||
int pad = MainActivity.instance.DpToPx(30);
|
||||
|
||||
@@ -103,8 +103,21 @@ namespace Opus.Fragments
|
||||
adapter.ItemLongCLick += ListView_ItemLongClick;
|
||||
ListView.SetItemAnimator(new DefaultItemAnimator());
|
||||
|
||||
//Youtube saved playlists
|
||||
List<PlaylistItem> yt = await PlaylistManager.GetSavedYoutubePlaylists(SyncedPlaylists, YoutubeItemSynced);
|
||||
|
||||
if (instance == null)
|
||||
return;
|
||||
|
||||
if (yt != null)
|
||||
{
|
||||
int startPos = YoutubePlaylists.Count - 1;
|
||||
YoutubePlaylists.InsertRange(startPos, yt);
|
||||
adapter.NotifyItemRangeInserted(LocalPlaylists.Count + startPos, yt.Count);
|
||||
}
|
||||
|
||||
//Youtube owned playlists
|
||||
(List<PlaylistItem> yt, string err) = await PlaylistManager.GetOwnedYoutubePlaylists(SyncedPlaylists, YoutubeItemSynced);
|
||||
(yt, error) = await PlaylistManager.GetOwnedYoutubePlaylists(SyncedPlaylists, YoutubeItemSynced);
|
||||
|
||||
if (instance == null)
|
||||
return;
|
||||
@@ -117,29 +130,7 @@ namespace Opus.Fragments
|
||||
adapter.NotifyItemInserted(LocalPlaylists.Count + YoutubePlaylists.Count);
|
||||
populating = false;
|
||||
SyncError();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
int startPos = YoutubePlaylists.Count - 1;
|
||||
YoutubePlaylists.InsertRange(startPos, yt);
|
||||
adapter.NotifyItemRangeInserted(LocalPlaylists.Count + startPos, yt.Count);
|
||||
}
|
||||
|
||||
//Youtube saved playlists
|
||||
(yt, error) = await PlaylistManager.GetSavedYoutubePlaylists(SyncedPlaylists, YoutubeItemSynced);
|
||||
|
||||
if (instance == null)
|
||||
return;
|
||||
|
||||
if (yt == null)
|
||||
{
|
||||
YoutubePlaylists.Remove(Loading);
|
||||
adapter.NotifyItemRemoved(LocalPlaylists.Count + YoutubePlaylists.Count);
|
||||
YoutubePlaylists.Add(new PlaylistItem("Error", null)); //Should use the "error" var here
|
||||
adapter.NotifyItemInserted(LocalPlaylists.Count + YoutubePlaylists.Count);
|
||||
populating = false;
|
||||
SyncError();
|
||||
adapter.forkSaved = true;
|
||||
return;
|
||||
}
|
||||
else
|
||||
@@ -272,24 +263,26 @@ namespace Opus.Fragments
|
||||
.SetTitle(Resource.String.add_playlist_msg)
|
||||
.SetView(view)
|
||||
.SetNegativeButton(Resource.String.cancel, (s, eventArgs) => { })
|
||||
.SetPositiveButton(Resource.String.add, /*async*/ (s, eventArgs) =>
|
||||
.SetPositiveButton(Resource.String.add, async (s, eventArgs) =>
|
||||
{
|
||||
string url = view.FindViewById<EditText>(Resource.Id.playlistURL).Text;
|
||||
string shrinkedURL = url.Substring(url.IndexOf('=') + 1);
|
||||
string playlistID = shrinkedURL;
|
||||
if (shrinkedURL.Contains("&"))
|
||||
if(YoutubeExplode.YoutubeClient.TryParsePlaylistId(view.FindViewById<EditText>(Resource.Id.playlistURL).Text, out string playlistID))
|
||||
{
|
||||
playlistID = shrinkedURL.Substring(0, shrinkedURL.IndexOf("&"));
|
||||
}
|
||||
/*await*/ PlaylistManager.ForkPlaylist(playlistID);
|
||||
PlaylistManager.ForkPlaylist(await PlaylistManager.GetPlaylist(playlistID));
|
||||
|
||||
if (YoutubePlaylists.Count == 3 && YoutubePlaylists[1].Name == "EMPTY")
|
||||
{
|
||||
YoutubePlaylists.RemoveAt(1);
|
||||
adapter.NotifyItemChanged(LocalPlaylists.Count + YoutubePlaylists.Count - 1);
|
||||
if (YoutubePlaylists.Count == 3 && YoutubePlaylists[1].Name == "EMPTY")
|
||||
{
|
||||
YoutubePlaylists.RemoveAt(1);
|
||||
adapter.NotifyItemChanged(LocalPlaylists.Count + YoutubePlaylists.Count - 1);
|
||||
}
|
||||
else
|
||||
adapter.NotifyItemInserted(LocalPlaylists.Count + YoutubePlaylists.Count);
|
||||
}
|
||||
else
|
||||
adapter.NotifyItemInserted(LocalPlaylists.Count + YoutubePlaylists.Count);
|
||||
{
|
||||
Snackbar snackBar = Snackbar.Make(MainActivity.instance.FindViewById(Resource.Id.snackBar), MainActivity.instance.GetString(Resource.String.badplaylisturl), Snackbar.LengthLong);
|
||||
snackBar.View.FindViewById<TextView>(Resource.Id.snackbar_text).SetTextColor(Color.White);
|
||||
snackBar.Show();
|
||||
}
|
||||
})
|
||||
.Show();
|
||||
return;
|
||||
@@ -309,7 +302,7 @@ namespace Opus.Fragments
|
||||
MainActivity.instance.contentRefresh.Refresh -= OnRefresh;
|
||||
MainActivity.instance.contentRefresh.Refresh -= OnRefresh;
|
||||
|
||||
MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(playlist, false)).AddToBackStack("Playlist Track").Commit();
|
||||
MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(playlist)).AddToBackStack("Playlist Track").Commit();
|
||||
}
|
||||
|
||||
private void ListView_ItemLongClick(object sender, int position)
|
||||
@@ -441,7 +434,9 @@ namespace Opus.Fragments
|
||||
{
|
||||
actions.Add(new BottomSheetAction(Resource.Drawable.Delete, Resources.GetString(Resource.String.unfork), (sender, eventArg) =>
|
||||
{
|
||||
PlaylistManager.Unfork(Position, item.YoutubeID);
|
||||
PlaylistManager.Unfork(item);
|
||||
YoutubePlaylists.RemoveAt(Position - LocalPlaylists.Count);
|
||||
adapter.NotifyItemRemoved(Position);
|
||||
bottomSheet.Dismiss();
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@ namespace Opus.Fragments
|
||||
private string query;
|
||||
private string nextPageToken = null;
|
||||
public bool fullyLoadded = true;
|
||||
public bool forked;
|
||||
public bool lastVisible = false;
|
||||
public bool useHeader = true;
|
||||
public bool navigating = false;
|
||||
private bool isForked;
|
||||
private bool loading = false;
|
||||
|
||||
|
||||
@@ -171,7 +171,12 @@ namespace Opus.Fragments
|
||||
break;
|
||||
|
||||
case Resource.Id.fork:
|
||||
PlaylistManager.ForkPlaylist(item.YoutubeID);
|
||||
if (isForked)
|
||||
PlaylistManager.Unfork(item);
|
||||
else
|
||||
PlaylistManager.ForkPlaylist(item);
|
||||
|
||||
isForked = !isForked;
|
||||
break;
|
||||
|
||||
case Resource.Id.addToQueue:
|
||||
@@ -208,12 +213,12 @@ namespace Opus.Fragments
|
||||
void PlaylistMore(object sender, System.EventArgs eventArgs)
|
||||
{
|
||||
PopupMenu menu = new PopupMenu(MainActivity.instance, MainActivity.instance.FindViewById<ImageButton>(Resource.Id.headerMore));
|
||||
if (item.LocalID == 0 && item.HasWritePermission)
|
||||
if (item.LocalID == -1 && item.HasWritePermission)
|
||||
menu.Inflate(Resource.Menu.ytplaylist_header_more);
|
||||
else if (item.LocalID == 0 && forked)
|
||||
else if (item.LocalID == -1 && isForked)
|
||||
menu.Inflate(Resource.Menu.ytplaylistnowrite_forked_header_more);
|
||||
else if (item.LocalID == -1)
|
||||
menu.Inflate(Resource.Menu.ytplaylistnowrite_header_more);
|
||||
else if (item.LocalID == 0)
|
||||
menu.Inflate(Resource.Menu.ytplaylist_nowrite_nofork_header_more);
|
||||
else
|
||||
menu.Inflate(Resource.Menu.playlist_header_more);
|
||||
|
||||
@@ -236,13 +241,17 @@ namespace Opus.Fragments
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static Fragment NewInstance(PlaylistItem item, bool forked)
|
||||
public static Fragment NewInstance(PlaylistItem item)
|
||||
{
|
||||
instance = new PlaylistTracks { Arguments = new Bundle() };
|
||||
instance.item = item;
|
||||
instance.forked = forked;
|
||||
instance.useHeader = true;
|
||||
instance.fullyLoadded = item.LocalID != 0 && item.LocalID != -1;
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
instance.isForked = await PlaylistManager.IsForked(item);
|
||||
});
|
||||
return instance;
|
||||
}
|
||||
|
||||
@@ -256,7 +265,6 @@ namespace Opus.Fragments
|
||||
if (await MainActivity.instance.GetReadPermission() == false)
|
||||
{
|
||||
MainActivity.instance.FindViewById(Resource.Id.loading).Visibility = ViewStates.Gone;
|
||||
//adapter.ErrorMSG = GetString(Resource.String.no_permission);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +190,6 @@ namespace Opus.Fragments
|
||||
}
|
||||
|
||||
SearchableActivity.IgnoreMyself = false;
|
||||
Console.WriteLine("&Waiting for youtube");
|
||||
|
||||
if (!await MainActivity.instance.WaitForYoutube())
|
||||
{
|
||||
@@ -201,8 +200,6 @@ namespace Opus.Fragments
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine("&Request");
|
||||
|
||||
try
|
||||
{
|
||||
SearchResource.ListRequest searchResult = YoutubeManager.YoutubeService.Search.List("snippet");
|
||||
@@ -241,8 +238,6 @@ namespace Opus.Fragments
|
||||
nextPageToken = searchReponse.NextPageToken;
|
||||
result = new List<YtFile>();
|
||||
|
||||
Console.WriteLine("&Request done");
|
||||
|
||||
foreach (var video in searchReponse.Items)
|
||||
result.Add(GetYtFileFromSearchResult(video));
|
||||
|
||||
@@ -349,7 +344,7 @@ namespace Opus.Fragments
|
||||
SearchableActivity.IgnoreMyself = true;
|
||||
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, PlaylistTracks.NewInstance(result[position].playlist, false)).AddToBackStack("Playlist Track").Commit();
|
||||
MainActivity.instance.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.contentView, PlaylistTracks.NewInstance(result[position].playlist)).AddToBackStack("Playlist Track").Commit();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -439,7 +434,7 @@ namespace Opus.Fragments
|
||||
}),
|
||||
new BottomSheetAction(Resource.Drawable.LibraryAdd, MainActivity.instance.Resources.GetString(Resource.String.add_to_library), (sender, eventArg) =>
|
||||
{
|
||||
PlaylistManager.ForkPlaylist(item.YoutubeID);
|
||||
PlaylistManager.ForkPlaylist(item);
|
||||
bottomSheet.Dismiss();
|
||||
}),
|
||||
new BottomSheetAction(Resource.Drawable.Download, MainActivity.instance.Resources.GetString(Resource.String.download), (sender, eventArg) =>
|
||||
|
||||
@@ -628,9 +628,6 @@
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\smallLoading.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\menu\ytplaylist_nowrite_nofork_header_more.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\layout\SearchLayout.xml" />
|
||||
</ItemGroup>
|
||||
@@ -895,7 +892,12 @@
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<AndroidResource Include="Resources\menu\ytplaylistnowrite_forked_header_more.xml">
|
||||
<Generator>MSBuild:UpdateGeneratedFiles</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</AndroidResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||
<Import Project="..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.targets" Condition="Exists('..\packages\Xamarin.Android.Support.Animated.Vector.Drawable.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.Animated.Vector.Drawable.targets')" />
|
||||
<Import Project="..\packages\Xamarin.Android.Support.v7.Preference.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.Preference.targets" Condition="Exists('..\packages\Xamarin.Android.Support.v7.Preference.25.4.0.2\build\MonoAndroid70\Xamarin.Android.Support.v7.Preference.targets')" />
|
||||
|
||||
344
Opus/Resources/Resource.Designer.cs
generated
344
Opus/Resources/Resource.Designer.cs
generated
@@ -7045,7 +7045,7 @@ namespace Opus
|
||||
public const int ytplaylist_header_more = 2131755017;
|
||||
|
||||
// aapt resource value: 0x7f10000a
|
||||
public const int ytplaylist_nowrite_nofork_header_more = 2131755018;
|
||||
public const int ytplaylistnowrite_forked_header_more = 2131755018;
|
||||
|
||||
// aapt resource value: 0x7f10000b
|
||||
public const int ytplaylistnowrite_header_more = 2131755019;
|
||||
@@ -7186,14 +7186,14 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d0072
|
||||
public const int abc_toolbar_collapse_description = 2131558514;
|
||||
|
||||
// aapt resource value: 0x7f0d012d
|
||||
public const int add = 2131558701;
|
||||
// aapt resource value: 0x7f0d0131
|
||||
public const int add = 2131558705;
|
||||
|
||||
// aapt resource value: 0x7f0d00fc
|
||||
public const int add_playlist = 2131558652;
|
||||
|
||||
// aapt resource value: 0x7f0d010c
|
||||
public const int add_playlist_msg = 2131558668;
|
||||
// aapt resource value: 0x7f0d010e
|
||||
public const int add_playlist_msg = 2131558670;
|
||||
|
||||
// aapt resource value: 0x7f0d00e0
|
||||
public const int add_to_library = 2131558624;
|
||||
@@ -7204,8 +7204,8 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00da
|
||||
public const int add_to_queue = 2131558618;
|
||||
|
||||
// aapt resource value: 0x7f0d0116
|
||||
public const int album = 2131558678;
|
||||
// aapt resource value: 0x7f0d011a
|
||||
public const int album = 2131558682;
|
||||
|
||||
// aapt resource value: 0x7f0d00ea
|
||||
public const int all = 2131558634;
|
||||
@@ -7213,14 +7213,14 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d0080
|
||||
public const int appbar_scrolling_view_behavior = 2131558528;
|
||||
|
||||
// aapt resource value: 0x7f0d0137
|
||||
public const int appearances = 2131558711;
|
||||
// aapt resource value: 0x7f0d013b
|
||||
public const int appearances = 2131558715;
|
||||
|
||||
// aapt resource value: 0x7f0d012a
|
||||
public const int apply = 2131558698;
|
||||
// aapt resource value: 0x7f0d012e
|
||||
public const int apply = 2131558702;
|
||||
|
||||
// aapt resource value: 0x7f0d0115
|
||||
public const int artist = 2131558677;
|
||||
// aapt resource value: 0x7f0d0119
|
||||
public const int artist = 2131558681;
|
||||
|
||||
// aapt resource value: 0x7f0d00cb
|
||||
public const int autoplay = 2131558603;
|
||||
@@ -7228,11 +7228,14 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00cc
|
||||
public const int autoplay_desc = 2131558604;
|
||||
|
||||
// aapt resource value: 0x7f0d0131
|
||||
public const int behavior = 2131558705;
|
||||
// aapt resource value: 0x7f0d0110
|
||||
public const int badplaylisturl = 2131558672;
|
||||
|
||||
// aapt resource value: 0x7f0d014f
|
||||
public const int beta_available = 2131558735;
|
||||
// aapt resource value: 0x7f0d0135
|
||||
public const int behavior = 2131558709;
|
||||
|
||||
// aapt resource value: 0x7f0d0153
|
||||
public const int beta_available = 2131558739;
|
||||
|
||||
// aapt resource value: 0x7f0d0081
|
||||
public const int bottom_sheet_behavior = 2131558529;
|
||||
@@ -7240,17 +7243,17 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00b4
|
||||
public const int browse = 2131558580;
|
||||
|
||||
// aapt resource value: 0x7f0d012b
|
||||
public const int cancel = 2131558699;
|
||||
// aapt resource value: 0x7f0d012f
|
||||
public const int cancel = 2131558703;
|
||||
|
||||
// aapt resource value: 0x7f0d0155
|
||||
public const int cancelling = 2131558741;
|
||||
// aapt resource value: 0x7f0d0159
|
||||
public const int cancelling = 2131558745;
|
||||
|
||||
// aapt resource value: 0x7f0d00f2
|
||||
public const int cant_delete = 2131558642;
|
||||
|
||||
// aapt resource value: 0x7f0d0152
|
||||
public const int cant_play_non_youtube = 2131558738;
|
||||
// aapt resource value: 0x7f0d0156
|
||||
public const int cant_play_non_youtube = 2131558742;
|
||||
|
||||
// aapt resource value: 0x7f0d00b9
|
||||
public const int cast = 2131558585;
|
||||
@@ -7333,11 +7336,11 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d0015
|
||||
public const int cast_play = 2131558421;
|
||||
|
||||
// aapt resource value: 0x7f0d0128
|
||||
public const int cast_queue_push = 2131558696;
|
||||
// aapt resource value: 0x7f0d012c
|
||||
public const int cast_queue_push = 2131558700;
|
||||
|
||||
// aapt resource value: 0x7f0d0129
|
||||
public const int cast_queue_pushed = 2131558697;
|
||||
// aapt resource value: 0x7f0d012d
|
||||
public const int cast_queue_pushed = 2131558701;
|
||||
|
||||
// aapt resource value: 0x7f0d0016
|
||||
public const int cast_rewind = 2131558422;
|
||||
@@ -7387,11 +7390,11 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d0025
|
||||
public const int cast_unmute = 2131558437;
|
||||
|
||||
// aapt resource value: 0x7f0d0118
|
||||
public const int change_albumart = 2131558680;
|
||||
// aapt resource value: 0x7f0d011c
|
||||
public const int change_albumart = 2131558684;
|
||||
|
||||
// aapt resource value: 0x7f0d011d
|
||||
public const int changes_saved = 2131558685;
|
||||
// aapt resource value: 0x7f0d0121
|
||||
public const int changes_saved = 2131558689;
|
||||
|
||||
// aapt resource value: 0x7f0d00ec
|
||||
public const int channels = 2131558636;
|
||||
@@ -7402,8 +7405,8 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d0083
|
||||
public const int character_counter_pattern = 2131558531;
|
||||
|
||||
// aapt resource value: 0x7f0d013d
|
||||
public const int check_updates = 2131558717;
|
||||
// aapt resource value: 0x7f0d0141
|
||||
public const int check_updates = 2131558721;
|
||||
|
||||
// aapt resource value: 0x7f0d00b0
|
||||
public const int clientID = 2131558576;
|
||||
@@ -7465,14 +7468,14 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d003b
|
||||
public const int common_signin_button_text_long = 2131558459;
|
||||
|
||||
// aapt resource value: 0x7f0d0127
|
||||
public const int completed = 2131558695;
|
||||
// aapt resource value: 0x7f0d012b
|
||||
public const int completed = 2131558699;
|
||||
|
||||
// aapt resource value: 0x7f0d0149
|
||||
public const int country_blocked = 2131558729;
|
||||
// aapt resource value: 0x7f0d014d
|
||||
public const int country_blocked = 2131558733;
|
||||
|
||||
// aapt resource value: 0x7f0d0111
|
||||
public const int create_local = 2131558673;
|
||||
// aapt resource value: 0x7f0d0115
|
||||
public const int create_local = 2131558677;
|
||||
|
||||
// aapt resource value: 0x7f0d00cd
|
||||
public const int create_mix = 2131558605;
|
||||
@@ -7480,38 +7483,38 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00d1
|
||||
public const int create_mix_from_song = 2131558609;
|
||||
|
||||
// aapt resource value: 0x7f0d010d
|
||||
public const int create_playlist = 2131558669;
|
||||
// aapt resource value: 0x7f0d0111
|
||||
public const int create_playlist = 2131558673;
|
||||
|
||||
// aapt resource value: 0x7f0d0113
|
||||
public const int create_synced = 2131558675;
|
||||
// aapt resource value: 0x7f0d0117
|
||||
public const int create_synced = 2131558679;
|
||||
|
||||
// aapt resource value: 0x7f0d0112
|
||||
public const int create_youtube = 2131558674;
|
||||
// aapt resource value: 0x7f0d0116
|
||||
public const int create_youtube = 2131558678;
|
||||
|
||||
// aapt resource value: 0x7f0d013b
|
||||
public const int dark_theme = 2131558715;
|
||||
// aapt resource value: 0x7f0d013f
|
||||
public const int dark_theme = 2131558719;
|
||||
|
||||
// aapt resource value: 0x7f0d00dc
|
||||
public const int delete = 2131558620;
|
||||
|
||||
// aapt resource value: 0x7f0d0108
|
||||
public const int delete_playlist = 2131558664;
|
||||
// aapt resource value: 0x7f0d010a
|
||||
public const int delete_playlist = 2131558666;
|
||||
|
||||
// aapt resource value: 0x7f0d0122
|
||||
public const int deleted_file = 2131558690;
|
||||
// aapt resource value: 0x7f0d0126
|
||||
public const int deleted_file = 2131558694;
|
||||
|
||||
// aapt resource value: 0x7f0d00d4
|
||||
public const int download = 2131558612;
|
||||
|
||||
// aapt resource value: 0x7f0d011a
|
||||
public const int download_albumart = 2131558682;
|
||||
// aapt resource value: 0x7f0d011e
|
||||
public const int download_albumart = 2131558686;
|
||||
|
||||
// aapt resource value: 0x7f0d0133
|
||||
public const int download_directory = 2131558707;
|
||||
// aapt resource value: 0x7f0d0137
|
||||
public const int download_directory = 2131558711;
|
||||
|
||||
// aapt resource value: 0x7f0d011b
|
||||
public const int download_meta = 2131558683;
|
||||
// aapt resource value: 0x7f0d011f
|
||||
public const int download_meta = 2131558687;
|
||||
|
||||
// aapt resource value: 0x7f0d00ee
|
||||
public const int download_path_error = 2131558638;
|
||||
@@ -7519,20 +7522,20 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00ed
|
||||
public const int download_path_not_set = 2131558637;
|
||||
|
||||
// aapt resource value: 0x7f0d0121
|
||||
public const int download_queue = 2131558689;
|
||||
// aapt resource value: 0x7f0d0125
|
||||
public const int download_queue = 2131558693;
|
||||
|
||||
// aapt resource value: 0x7f0d00f0
|
||||
public const int downloading = 2131558640;
|
||||
|
||||
// aapt resource value: 0x7f0d0153
|
||||
public const int downloading_notification = 2131558739;
|
||||
// aapt resource value: 0x7f0d0157
|
||||
public const int downloading_notification = 2131558743;
|
||||
|
||||
// aapt resource value: 0x7f0d0125
|
||||
public const int downloading_status = 2131558693;
|
||||
// aapt resource value: 0x7f0d0129
|
||||
public const int downloading_status = 2131558697;
|
||||
|
||||
// aapt resource value: 0x7f0d0150
|
||||
public const int downloading_update = 2131558736;
|
||||
// aapt resource value: 0x7f0d0154
|
||||
public const int downloading_update = 2131558740;
|
||||
|
||||
// aapt resource value: 0x7f0d00d3
|
||||
public const int edit_metadata = 2131558611;
|
||||
@@ -7669,11 +7672,11 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00c4
|
||||
public const int hours = 2131558596;
|
||||
|
||||
// aapt resource value: 0x7f0d0123
|
||||
public const int initialization = 2131558691;
|
||||
// aapt resource value: 0x7f0d0127
|
||||
public const int initialization = 2131558695;
|
||||
|
||||
// aapt resource value: 0x7f0d012e
|
||||
public const int later = 2131558702;
|
||||
// aapt resource value: 0x7f0d0132
|
||||
public const int later = 2131558706;
|
||||
|
||||
// aapt resource value: 0x7f0d00d7
|
||||
public const int list_songs = 2131558615;
|
||||
@@ -7687,26 +7690,26 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00fa
|
||||
public const int local_playlists = 2131558650;
|
||||
|
||||
// aapt resource value: 0x7f0d0141
|
||||
public const int log_in = 2131558721;
|
||||
// aapt resource value: 0x7f0d0145
|
||||
public const int log_in = 2131558725;
|
||||
|
||||
// aapt resource value: 0x7f0d0142
|
||||
public const int log_out = 2131558722;
|
||||
// aapt resource value: 0x7f0d0146
|
||||
public const int log_out = 2131558726;
|
||||
|
||||
// aapt resource value: 0x7f0d0140
|
||||
public const int logged_in = 2131558720;
|
||||
// aapt resource value: 0x7f0d0144
|
||||
public const int logged_in = 2131558724;
|
||||
|
||||
// aapt resource value: 0x7f0d0134
|
||||
public const int max_download = 2131558708;
|
||||
// aapt resource value: 0x7f0d0138
|
||||
public const int max_download = 2131558712;
|
||||
|
||||
// aapt resource value: 0x7f0d0135
|
||||
public const int max_download_dialog = 2131558709;
|
||||
// aapt resource value: 0x7f0d0139
|
||||
public const int max_download_dialog = 2131558713;
|
||||
|
||||
// aapt resource value: 0x7f0d0124
|
||||
public const int metadata = 2131558692;
|
||||
// aapt resource value: 0x7f0d0128
|
||||
public const int metadata = 2131558696;
|
||||
|
||||
// aapt resource value: 0x7f0d011e
|
||||
public const int metdata_error_noid = 2131558686;
|
||||
// aapt resource value: 0x7f0d0122
|
||||
public const int metdata_error_noid = 2131558690;
|
||||
|
||||
// aapt resource value: 0x7f0d00c1
|
||||
public const int minute = 2131558593;
|
||||
@@ -7717,11 +7720,11 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00e4
|
||||
public const int more = 2131558628;
|
||||
|
||||
// aapt resource value: 0x7f0d011f
|
||||
public const int mount_error = 2131558687;
|
||||
// aapt resource value: 0x7f0d0123
|
||||
public const int mount_error = 2131558691;
|
||||
|
||||
// aapt resource value: 0x7f0d0120
|
||||
public const int mount_error_action = 2131558688;
|
||||
// aapt resource value: 0x7f0d0124
|
||||
public const int mount_error_action = 2131558692;
|
||||
|
||||
// aapt resource value: 0x7f0d0040
|
||||
public const int mr_button_content_description = 2131558464;
|
||||
@@ -7798,14 +7801,14 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d0087
|
||||
public const int mtrl_chip_close_icon_content_description = 2131558535;
|
||||
|
||||
// aapt resource value: 0x7f0d0110
|
||||
public const int new_playlist = 2131558672;
|
||||
// aapt resource value: 0x7f0d0114
|
||||
public const int new_playlist = 2131558676;
|
||||
|
||||
// aapt resource value: 0x7f0d00be
|
||||
public const int next_loading = 2131558590;
|
||||
|
||||
// aapt resource value: 0x7f0d0130
|
||||
public const int no = 2131558704;
|
||||
// aapt resource value: 0x7f0d0134
|
||||
public const int no = 2131558708;
|
||||
|
||||
// aapt resource value: 0x7f0d00f7
|
||||
public const int no_channel = 2131558647;
|
||||
@@ -7813,8 +7816,8 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00f6
|
||||
public const int no_lives = 2131558646;
|
||||
|
||||
// aapt resource value: 0x7f0d0144
|
||||
public const int no_permission = 2131558724;
|
||||
// aapt resource value: 0x7f0d0148
|
||||
public const int no_permission = 2131558728;
|
||||
|
||||
// aapt resource value: 0x7f0d00f5
|
||||
public const int no_playlist = 2131558645;
|
||||
@@ -7825,17 +7828,17 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00e9
|
||||
public const int no_song = 2131558633;
|
||||
|
||||
// aapt resource value: 0x7f0d0145
|
||||
public const int no_song_mix = 2131558725;
|
||||
// aapt resource value: 0x7f0d0149
|
||||
public const int no_song_mix = 2131558729;
|
||||
|
||||
// aapt resource value: 0x7f0d00f4
|
||||
public const int no_track = 2131558644;
|
||||
|
||||
// aapt resource value: 0x7f0d013f
|
||||
public const int not_log = 2131558719;
|
||||
// aapt resource value: 0x7f0d0143
|
||||
public const int not_log = 2131558723;
|
||||
|
||||
// aapt resource value: 0x7f0d014a
|
||||
public const int not_streamable = 2131558730;
|
||||
// aapt resource value: 0x7f0d014e
|
||||
public const int not_streamable = 2131558734;
|
||||
|
||||
// aapt resource value: 0x7f0d00bd
|
||||
public const int nothing = 2131558589;
|
||||
@@ -7843,14 +7846,14 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00c0
|
||||
public const int off = 2131558592;
|
||||
|
||||
// aapt resource value: 0x7f0d012c
|
||||
public const int ok = 2131558700;
|
||||
// aapt resource value: 0x7f0d0130
|
||||
public const int ok = 2131558704;
|
||||
|
||||
// aapt resource value: 0x7f0d00c6
|
||||
public const int open_youtube = 2131558598;
|
||||
|
||||
// aapt resource value: 0x7f0d013c
|
||||
public const int others = 2131558716;
|
||||
// aapt resource value: 0x7f0d0140
|
||||
public const int others = 2131558720;
|
||||
|
||||
// aapt resource value: 0x7f0d0088
|
||||
public const int password_toggle_content_description = 2131558536;
|
||||
@@ -7870,8 +7873,8 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00c8
|
||||
public const int paused = 2131558600;
|
||||
|
||||
// aapt resource value: 0x7f0d0119
|
||||
public const int pick_album_local = 2131558681;
|
||||
// aapt resource value: 0x7f0d011d
|
||||
public const int pick_album_local = 2131558685;
|
||||
|
||||
// aapt resource value: 0x7f0d00ce
|
||||
public const int play = 2131558606;
|
||||
@@ -7888,17 +7891,26 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00c7
|
||||
public const int playing = 2131558599;
|
||||
|
||||
// aapt resource value: 0x7f0d0107
|
||||
public const int playlist_add_song_not_found = 2131558663;
|
||||
// aapt resource value: 0x7f0d0109
|
||||
public const int playlist_add_song_not_found = 2131558665;
|
||||
|
||||
// aapt resource value: 0x7f0d0105
|
||||
public const int playlist_already_saved = 2131558661;
|
||||
// aapt resource value: 0x7f0d0106
|
||||
public const int playlist_already_saved = 2131558662;
|
||||
|
||||
// aapt resource value: 0x7f0d0102
|
||||
public const int playlist_empty = 2131558658;
|
||||
|
||||
// aapt resource value: 0x7f0d0106
|
||||
public const int playlist_not_found = 2131558662;
|
||||
// aapt resource value: 0x7f0d010f
|
||||
public const int playlist_fork = 2131558671;
|
||||
|
||||
// aapt resource value: 0x7f0d0108
|
||||
public const int playlist_not_found = 2131558664;
|
||||
|
||||
// aapt resource value: 0x7f0d0105
|
||||
public const int playlist_saved = 2131558661;
|
||||
|
||||
// aapt resource value: 0x7f0d0107
|
||||
public const int playlist_unsaved = 2131558663;
|
||||
|
||||
// aapt resource value: 0x7f0d00b5
|
||||
public const int playlists = 2131558581;
|
||||
@@ -7933,8 +7945,8 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00db
|
||||
public const int rename = 2131558619;
|
||||
|
||||
// aapt resource value: 0x7f0d0109
|
||||
public const int rename_playlist = 2131558665;
|
||||
// aapt resource value: 0x7f0d010b
|
||||
public const int rename_playlist = 2131558667;
|
||||
|
||||
// aapt resource value: 0x7f0d00b6
|
||||
public const int repeat = 2131558582;
|
||||
@@ -7942,11 +7954,11 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00ca
|
||||
public const int save_as_playlist = 2131558602;
|
||||
|
||||
// aapt resource value: 0x7f0d010f
|
||||
public const int save_folder_playlist = 2131558671;
|
||||
// aapt resource value: 0x7f0d0113
|
||||
public const int save_folder_playlist = 2131558675;
|
||||
|
||||
// aapt resource value: 0x7f0d010e
|
||||
public const int save_playlist = 2131558670;
|
||||
// aapt resource value: 0x7f0d0112
|
||||
public const int save_playlist = 2131558674;
|
||||
|
||||
// aapt resource value: 0x7f0d0073
|
||||
public const int search_menu_title = 2131558515;
|
||||
@@ -7978,8 +7990,8 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00df
|
||||
public const int stop_sync = 2131558623;
|
||||
|
||||
// aapt resource value: 0x7f0d010a
|
||||
public const int stop_syncing = 2131558666;
|
||||
// aapt resource value: 0x7f0d010c
|
||||
public const int stop_syncing = 2131558668;
|
||||
|
||||
// aapt resource value: 0x7f0d003d
|
||||
public const int summary_collapsed_preference_list = 2131558461;
|
||||
@@ -7990,65 +8002,65 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00de
|
||||
public const int sync_now = 2131558622;
|
||||
|
||||
// aapt resource value: 0x7f0d0136
|
||||
public const int sync_remove = 2131558710;
|
||||
// aapt resource value: 0x7f0d013a
|
||||
public const int sync_remove = 2131558714;
|
||||
|
||||
// aapt resource value: 0x7f0d00f1
|
||||
public const int syncing = 2131558641;
|
||||
|
||||
// aapt resource value: 0x7f0d0154
|
||||
public const int tap_details = 2131558740;
|
||||
// aapt resource value: 0x7f0d0158
|
||||
public const int tap_details = 2131558744;
|
||||
|
||||
// aapt resource value: 0x7f0d0138
|
||||
public const int theme = 2131558712;
|
||||
// aapt resource value: 0x7f0d013c
|
||||
public const int theme = 2131558716;
|
||||
|
||||
// aapt resource value: 0x7f0d0139
|
||||
public const int theme_dialog = 2131558713;
|
||||
// aapt resource value: 0x7f0d013d
|
||||
public const int theme_dialog = 2131558717;
|
||||
|
||||
// aapt resource value: 0x7f0d00c5
|
||||
public const int timer = 2131558597;
|
||||
|
||||
// aapt resource value: 0x7f0d014b
|
||||
public const int timout = 2131558731;
|
||||
|
||||
// aapt resource value: 0x7f0d0118
|
||||
public const int title = 2131558680;
|
||||
|
||||
// aapt resource value: 0x7f0d0147
|
||||
public const int timout = 2131558727;
|
||||
public const int undo = 2131558727;
|
||||
|
||||
// aapt resource value: 0x7f0d0114
|
||||
public const int title = 2131558676;
|
||||
|
||||
// aapt resource value: 0x7f0d0143
|
||||
public const int undo = 2131558723;
|
||||
|
||||
// aapt resource value: 0x7f0d011c
|
||||
public const int undo_change = 2131558684;
|
||||
// aapt resource value: 0x7f0d0120
|
||||
public const int undo_change = 2131558688;
|
||||
|
||||
// aapt resource value: 0x7f0d00e1
|
||||
public const int unfork = 2131558625;
|
||||
|
||||
// aapt resource value: 0x7f0d010b
|
||||
public const int unfork_playlist = 2131558667;
|
||||
// aapt resource value: 0x7f0d010d
|
||||
public const int unfork_playlist = 2131558669;
|
||||
|
||||
// aapt resource value: 0x7f0d0148
|
||||
public const int unknow = 2131558728;
|
||||
// aapt resource value: 0x7f0d014c
|
||||
public const int unknow = 2131558732;
|
||||
|
||||
// aapt resource value: 0x7f0d00bc
|
||||
public const int up_next = 2131558588;
|
||||
|
||||
// aapt resource value: 0x7f0d014e
|
||||
public const int up_to_date = 2131558734;
|
||||
// aapt resource value: 0x7f0d0152
|
||||
public const int up_to_date = 2131558738;
|
||||
|
||||
// aapt resource value: 0x7f0d0126
|
||||
public const int up_to_date_status = 2131558694;
|
||||
// aapt resource value: 0x7f0d012a
|
||||
public const int up_to_date_status = 2131558698;
|
||||
|
||||
// aapt resource value: 0x7f0d014c
|
||||
public const int update = 2131558732;
|
||||
|
||||
// aapt resource value: 0x7f0d014d
|
||||
public const int update_message = 2131558733;
|
||||
|
||||
// aapt resource value: 0x7f0d014b
|
||||
public const int update_no_internet = 2131558731;
|
||||
// aapt resource value: 0x7f0d0150
|
||||
public const int update = 2131558736;
|
||||
|
||||
// aapt resource value: 0x7f0d0151
|
||||
public const int updating = 2131558737;
|
||||
public const int update_message = 2131558737;
|
||||
|
||||
// aapt resource value: 0x7f0d014f
|
||||
public const int update_no_internet = 2131558735;
|
||||
|
||||
// aapt resource value: 0x7f0d0155
|
||||
public const int updating = 2131558741;
|
||||
|
||||
// aapt resource value: 0x7f0d003e
|
||||
public const int v7_preference_off = 2131558462;
|
||||
@@ -8056,20 +8068,20 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d003f
|
||||
public const int v7_preference_on = 2131558463;
|
||||
|
||||
// aapt resource value: 0x7f0d0142
|
||||
public const int version = 2131558722;
|
||||
|
||||
// aapt resource value: 0x7f0d0136
|
||||
public const int volume = 2131558710;
|
||||
|
||||
// aapt resource value: 0x7f0d013e
|
||||
public const int version = 2131558718;
|
||||
public const int white_theme = 2131558718;
|
||||
|
||||
// aapt resource value: 0x7f0d0132
|
||||
public const int volume = 2131558706;
|
||||
// aapt resource value: 0x7f0d0133
|
||||
public const int yes = 2131558707;
|
||||
|
||||
// aapt resource value: 0x7f0d013a
|
||||
public const int white_theme = 2131558714;
|
||||
|
||||
// aapt resource value: 0x7f0d012f
|
||||
public const int yes = 2131558703;
|
||||
|
||||
// aapt resource value: 0x7f0d0146
|
||||
public const int youtube_endpoint = 2131558726;
|
||||
// aapt resource value: 0x7f0d014a
|
||||
public const int youtube_endpoint = 2131558730;
|
||||
|
||||
// aapt resource value: 0x7f0d00fd
|
||||
public const int youtube_loading_error = 2131558653;
|
||||
@@ -8083,8 +8095,8 @@ namespace Opus
|
||||
// aapt resource value: 0x7f0d00b7
|
||||
public const int youtube_search = 2131558583;
|
||||
|
||||
// aapt resource value: 0x7f0d0117
|
||||
public const int youtubeid = 2131558679;
|
||||
// aapt resource value: 0x7f0d011b
|
||||
public const int youtubeid = 2131558683;
|
||||
|
||||
// aapt resource value: 0x7f0d00b2
|
||||
public const int yt_api_key = 2131558578;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:text="You can add any youtube playlist by entering the playlist url in this field. You can find a playlist url by clicking the share button on the youtube app then click Copy Link. \nWarning: it will add a section "Saved Playlists" on your youtube channel."/>
|
||||
android:text="@string/playlist_fork"/>
|
||||
<EditText
|
||||
android:id="@+id/playlistURL"
|
||||
android:inputType="text"
|
||||
|
||||
15
Opus/Resources/menu/ytplaylistnowrite_forked_header_more.xml
Normal file
15
Opus/Resources/menu/ytplaylistnowrite_forked_header_more.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
<item
|
||||
android:id="@+id/download"
|
||||
android:title="@string/sync" />
|
||||
<item
|
||||
android:id="@+id/fork"
|
||||
android:title="@string/unfork" />
|
||||
<item
|
||||
android:id="@+id/addToQueue"
|
||||
android:title="@string/add_to_queue" />
|
||||
<item
|
||||
android:id="@+id/delete"
|
||||
android:title="@string/delete" />
|
||||
</menu>
|
||||
@@ -3,6 +3,9 @@
|
||||
<item
|
||||
android:id="@+id/download"
|
||||
android:title="@string/sync" />
|
||||
<item
|
||||
android:id="@+id/fork"
|
||||
android:title="@string/add_to_library" />
|
||||
<item
|
||||
android:id="@+id/addToQueue"
|
||||
android:title="@string/add_to_queue" />
|
||||
|
||||
@@ -103,7 +103,9 @@
|
||||
<string name="playlist_empty">Cette playlist est vide.</string>
|
||||
<string name="remove_from_playlist">Enlever %1$s de la playlist ?</string> <!--%1$s will be replaced by the song name-->
|
||||
<string name="removed_from_playlist"> a été enlevé de la playlist.</string>
|
||||
<string name="playlist_saved">Cette playlist a été ajoutée à votre bibliothèque.</string>
|
||||
<string name="playlist_already_saved">Cette playlist a déja été ajoutée à votre bibliothèque.</string>
|
||||
<string name="playlist_unsaved">Cette playlist a été enlevée de votre bibliothèque.</string>
|
||||
<string name="playlist_not_found">Aucune playlist n\'existe avec cet id ou cette url.</string>
|
||||
<string name="playlist_add_song_not_found">Musique non trouvée sur youtube, impossible de l\'ajouter à une playlist youtube.</string>
|
||||
<string name="delete_playlist">Voulez vous supprimer la playlist \"%1$s\" ?</string> <!--%1$s will be replaced by the playlist name-->
|
||||
@@ -111,6 +113,8 @@
|
||||
<string name="stop_syncing">Voulez vous arreter de synchroniser la playlist \"%1s$\" ?</string> <!--%1$s will be replaced by the playlist name-->
|
||||
<string name="unfork_playlist">Voulez vous supprimer la playlist \"%1$s"\" de votre bibliothèque ?</string> <!--%1$s will be replaced by the playlist name-->
|
||||
<string name="add_playlist_msg">Entrer l\'url ou l\'id de la playlist que vous voulez ajouter</string> <!--%1$s will be replaced by the playlist name-->
|
||||
<string name="playlist_fork">Ajoutez une playlist a votre bibliothèque en utilisant son URL.</string>
|
||||
<string name="badplaylisturl">Impossible de trouver une playlist correspondant a cette URL.</string>
|
||||
|
||||
<!--Add song to playlist-->
|
||||
<string name="create_playlist">Créer une nouvelle playlist</string>
|
||||
@@ -133,6 +137,8 @@
|
||||
<string name="undo_change">Annuler les modifications</string>
|
||||
<string name="changes_saved">Changement sauvegardé.</string>
|
||||
<string name="metdata_error_noid">Impossible de télécharger les metadatas depuis youtube, l\'id youtube n\'est pas défni.</string>
|
||||
<string name="mount_error">Il y a un problème avec votre disque de stockage, veuillez arreter de l\'utiliser ailleur et réessayer après.</string>
|
||||
<string name="mount_error_action">ABANDONNER ET QUITER</string>
|
||||
|
||||
<!--Download Queue-->
|
||||
<string name="download_queue">Liste de téléchargement</string>
|
||||
|
||||
@@ -103,15 +103,19 @@
|
||||
<string name="playlist_empty">This playlist is empty.</string>
|
||||
<string name="remove_from_playlist">Remove %1$s from playlist?</string> <!--%1$s will be replaced by the song name-->
|
||||
<string name="removed_from_playlist"> has been removed from the playlist.</string>
|
||||
<string name="playlist_saved">This playlist has been added to your library.</string>
|
||||
<string name="playlist_already_saved">Playlist already added to your library.</string>
|
||||
<string name="playlist_unsaved">This playlist has been removed from your library.</string>
|
||||
<string name="playlist_not_found">No playlist exist with this id or link.</string>
|
||||
<string name="playlist_add_song_not_found">Song can\'t be found on youtube, can\'t add it to a youtube playlist.</string>
|
||||
<string name="delete_playlist">Do you want to delete the playlist \"%1$s\"?</string> <!--%1$s will be replaced by the playlist name-->
|
||||
<string name="rename_playlist">Enter a new name for this playlist</string>
|
||||
<string name="stop_syncing">Do you want to stop syncing the playlist \"%1$s\"?</string> <!--%1$s will be replaced by the playlist name-->
|
||||
<string name="unfork_playlist">Do you want to remove \"%1$s"\" from your library?</string> <!--%1$s will be replaced by the playlist name-->
|
||||
<string name="add_playlist_msg">Enter the url or the id of the playlist you want to add</string> <!--%1$s will be replaced by the playlist name-->
|
||||
|
||||
<string name="add_playlist_msg">Enter the url or the id of the playlist you want to add</string>
|
||||
<string name="playlist_fork">Add a youtube playlist to your library by using it\'s url.</string>
|
||||
<string name="badplaylisturl">Can\'t find a playlist with this URL.</string>
|
||||
|
||||
<!--Add song to playlist-->
|
||||
<string name="create_playlist">Create a new playlist</string>
|
||||
<string name="save_playlist">Save song to...</string>
|
||||
|
||||
Reference in New Issue
Block a user