Skip to content

Commit

Permalink
Merge pull request #282 from zumicts/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
haroldma-zz committed Oct 1, 2015
2 parents 6015176 + c180909 commit c5d3839
Show file tree
Hide file tree
Showing 58 changed files with 1,924 additions and 326 deletions.
33 changes: 28 additions & 5 deletions Audiotica.Converters/WebToAlbumConverter.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Audiotica.Core.Common;
using Audiotica.Core.Extensions;
Expand Down Expand Up @@ -50,19 +51,41 @@ public async Task<Album> ConvertAsync(WebAlbum other, bool ignoreLibrary = false
{
await FillPartialAsync(other);

// fill the album partial for each track
foreach (var webSong in other.Tracks)
webSong.Album = other;

var album = new Album
{
Title = other.Title,
ArtworkUri = other.Artwork.ToString(),
Artist = await _webArtistConverter.ConvertAsync(other.Artist),
Year = other.ReleaseDate?.Year,
Tracks =
other.Tracks != null
? new OptimizedObservableCollection<Track>(
await Task.WhenAll(other.Tracks.Select(p => _webTrackConverter.ConvertAsync(p))))
: null
};

// TODO: ISupportIncrementalLoading?
if (other.Tracks != null)
{
// only let 10 concurrent conversions
using (var semaphoreSlim = new SemaphoreSlim(10, 10))
{
// ReSharper disable AccessToDisposedClosure
var trackTasks = other.Tracks.Select(async p =>
{
await semaphoreSlim.WaitAsync();
var track = await _webTrackConverter.ConvertAsync(p);
semaphoreSlim.Release();
return track;
});
album.Tracks =
other.Tracks != null
? new OptimizedObservableCollection<Track>(
await Task.WhenAll(trackTasks))
: null;
// ReSharper restore AccessToDisposedClosure
}
}

var libraryAlbum = _libraryService.Albums.FirstOrDefault(p => p.Title.EqualsIgnoreCase(album.Title));
other.PreviousConversion = libraryAlbum ?? album;

Expand Down
55 changes: 55 additions & 0 deletions Audiotica.Core/Extensions/CollectionExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,68 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

namespace Audiotica.Core.Extensions
{
public static class CollectionExtensions
{
private static readonly Random Random = new Random();

public static void Fill<T>(this T[] array, T value)
{
for (var i = 0; i < array.Length; i++)
{
array[i] = value;
}
}

public static void Sort<T>(this ObservableCollection<T> observable, Comparison<T> comparison)
{
var sorted = observable.ToList();
sorted.Sort(comparison);

var ptr = 0;
while (ptr < sorted.Count)
{
if (!observable[ptr].Equals(sorted[ptr]))
{
var t = observable[ptr];
observable.RemoveAt(ptr);
observable.Insert(sorted.IndexOf(t), t);
}
else
{
ptr++;
}
}
}

public static void AddRange<T>(this IList<T> collection, IEnumerable<T> items)
{
foreach (var item in items)
collection.Add(item);
}

public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> list)
{
var arr = list.ToArray();
Shuffle(arr);
return arr;
}

private static void Shuffle<T>(IList<T> array)
{
var n = array.Count;
for (var i = 0; i < n; i++)
{
// NextDouble returns a random number between 0 and 1.
// ... It is equivalent to Math.random() in Java.
var r = i + (int) (Random.NextDouble()*(n - i));
var t = array[r];
array[r] = array[i];
array[i] = t;
}
}
}
}
1 change: 1 addition & 0 deletions Audiotica.Core/Utilities/Interfaces/IAppSettingsUtility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ public interface IAppSettingsUtility
{
string DownloadsPath { get; set; }
string TempDownloadsPath { get; }
int Theme { get; set; }
}
}
3 changes: 3 additions & 0 deletions Audiotica.Database/Models/Playlist.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ public class Playlist
{
public string Id { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime EditedAt { get; set; }
public DateTime DeletedAt { get; set; }
public string Name { get; set; }
public bool IsVisible { get; set; }
public List<PlaylistTrack> Tracks { get; set; }
}
}
1 change: 0 additions & 1 deletion Audiotica.Database/Models/PlaylistTrack.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ namespace Audiotica.Database.Models
/// </summary>
public class PlaylistTrack
{
public string Id { get; set; }
public string TrackId { get; set; }

[JsonIgnore]
Expand Down
2 changes: 2 additions & 0 deletions Audiotica.Database/Models/Track.cs
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ public class TrackComparer : IEqualityComparer<Track>
{
public bool Equals(Track x, Track y)
{
if (x == null && y == null) return true;
if (x == null || y == null) return false;
if (x.IsFromLibrary && y.IsFromLibrary)
return x.Id == y.Id;
return GetHashCode(x) == GetHashCode(y);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ public static class ApplicationSettingsConstants
public const string IsAlbumAdaptiveColorEnabled = "IsAlbumAdaptiveColorEnabled";
public const string SongSort = "SongSort";
public const string AlbumSort = "AlbumSort";
public const string Theme = "Theme";
}
}
2 changes: 2 additions & 0 deletions Windows/Audiotica.Core.Windows/Helpers/FlyoutEx.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
using System;
using Windows.Foundation;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media;

namespace Audiotica.Core.Windows.Helpers
{
Expand Down
19 changes: 16 additions & 3 deletions Windows/Audiotica.Core.Windows/Messages/AddToPlaylistMessage.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,29 @@
using Audiotica.Database.Models;
using System.Collections.Generic;
using Audiotica.Database.Models;
using Newtonsoft.Json;

namespace Audiotica.Core.Windows.Messages
{
public class AddToPlaylistMessage
{
public AddToPlaylistMessage()
{
}

public AddToPlaylistMessage(QueueTrack track, int position)
{
Track = track;
Tracks = new List<QueueTrack> {track};
Position = position;
}

public AddToPlaylistMessage(List<QueueTrack> tracks, int position)
{
Tracks = tracks;
Position = position;
}

public QueueTrack Track { get; set; }
public List<QueueTrack> Tracks { get; set; }

public int Position { get; set; }
}
}
20 changes: 19 additions & 1 deletion Windows/Audiotica.Core.Windows/Utilities/AppSettingsUtility.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
using Windows.Storage;
using Windows.UI.Xaml;
using Audiotica.Core.Common;
using Audiotica.Core.Utilities.Interfaces;
using Audiotica.Core.Windows.Helpers;

namespace Audiotica.Core.Windows.Utilities
{
public class AppSettingsUtility : IAppSettingsUtility
public class AppSettingsUtility : ObservableObject, IAppSettingsUtility
{
private readonly ISettingsUtility _settingsUtility;
private int _theme;

public AppSettingsUtility(ISettingsUtility settingsUtility)
{
_settingsUtility = settingsUtility;
DownloadsPath = settingsUtility.Read("DownloadsPath", "virtual://Music/Audiotica/");
TempDownloadsPath = settingsUtility.Read("TempDownloadsPath", ApplicationData.Current.TemporaryFolder.Path);
_theme = _settingsUtility.Read(ApplicationSettingsConstants.Theme, (int)ElementTheme.Default);
}

public string DownloadsPath { get; set; }

public string TempDownloadsPath { get; }

public int Theme
{
get { return _theme; }
set
{
Set(ref _theme, value);
_settingsUtility.Write(ApplicationSettingsConstants.Theme, value);
}
}
}
}
4 changes: 2 additions & 2 deletions Windows/Audiotica.Windows.Player/ForegroundMessenger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public void Dispose()
public event EventHandler SkipToPrev;
public event EventHandler<string> TrackChanged;
public event EventHandler<List<QueueTrack>> UpdatePlaylist;
public event TypedEventHandler<QueueTrack, int> AddToPlaylist;
public event TypedEventHandler<List<QueueTrack>, int> AddToPlaylist;

/// <summary>
/// Raised when a message is recieved from the foreground app
Expand Down Expand Up @@ -66,7 +66,7 @@ private void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender,
{
var addMessage = message as AddToPlaylistMessage;
if (addMessage != null)
AddToPlaylist?.Invoke(addMessage.Track, addMessage.Position);
AddToPlaylist?.Invoke(addMessage.Tracks, addMessage.Position);
}
}
}
Expand Down
56 changes: 33 additions & 23 deletions Windows/Audiotica.Windows.Player/PlayerWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,14 @@ public void SkipToNext()
/// </summary>
public void SkipToPrev()
{
_smtcWrapper.PlaybackStatus = MediaPlaybackStatus.Changing;
_mediaPlaybackList.MovePrevious();
if (BackgroundMediaPlayer.Current.Position.TotalSeconds > 5)
BackgroundMediaPlayer.Current.Position = TimeSpan.Zero;

else
{
_smtcWrapper.PlaybackStatus = MediaPlaybackStatus.Changing;
_mediaPlaybackList.MovePrevious();
}

// TODO: Work around playlist bug that doesn't continue playing after a switch; remove later
BackgroundMediaPlayer.Current.Play();
Expand Down Expand Up @@ -156,23 +162,32 @@ public async void CreatePlaybackList(IEnumerable<QueueTrack> queues)
_mediaPlaybackList.CurrentItemChanged += MediaPlaybackListOnCurrentItemChanged;
}

public void AddToPlaybackList(QueueTrack queue, int position)
public async void AddToPlaybackList(List<QueueTrack> queue, int position)
{
if (_mediaPlaybackList == null
|| BackgroundMediaPlayer.Current.Source != _mediaPlaybackList)
CreatePlaybackList(new[] {queue});
CreatePlaybackList(queue);

else
{
var source = MediaSource.CreateFromUri(new Uri(queue.Track.AudioWebUri));
source.Queue(queue);

if (position > -1 && position < _mediaPlaybackList.Items.Count)
foreach (var item in queue)
{
_mediaPlaybackList.Items.Insert(position, new MediaPlaybackItem(source));
MediaSource source;
if (item.Track.Type == TrackType.Stream)
source = MediaSource.CreateFromUri(new Uri(item.Track.AudioWebUri));
else
{
source = MediaSource.CreateFromStorageFile(
await StorageHelper.GetFileFromPathAsync(item.Track.AudioLocalUri));
}
source.Queue(item);
var playbackItem = new MediaPlaybackItem(source);

if (position > -1 && position < _mediaPlaybackList.Items.Count)
_mediaPlaybackList.Items.Insert(position++, playbackItem);
else
_mediaPlaybackList.Items.Add(playbackItem);
}
else
_mediaPlaybackList.Items.Add(new MediaPlaybackItem(source));
}
}

Expand Down Expand Up @@ -338,7 +353,7 @@ private void UnsubscribeFromMessenger()
_foregroundMessenger.UpdatePlaylist -= ForegroundMessengerOnUpdatePlaylist;
}

private void ForegroundMessengerOnAddToPlaylist(QueueTrack queueTrack, int position)
private void ForegroundMessengerOnAddToPlaylist(List<QueueTrack> queueTrack, int position)
{
AddToPlaybackList(queueTrack, position);
}
Expand Down Expand Up @@ -367,21 +382,16 @@ private void ForegroundMessengerOnUpdatePlaylist(object sender, List<QueueTrack>

private void ForegroundMessengerOnTrackChanged(object sender, string queueId)
{
var index = _mediaPlaybackList.Items.ToList().FindIndex(i => i.Source.Queue().Id == queueId);
var queue = _mediaPlaybackList.Items.Select(p => p.Source.Queue()).ToList();
var index = queue.FindIndex(i => i.Id == queueId);
if (index < 0) return;
Debug.WriteLine("Skipping to track " + index);
_smtcWrapper.PlaybackStatus = MediaPlaybackStatus.Changing;

try
{
_mediaPlaybackList.MoveTo((uint) index);
_mediaPlaybackList.MoveTo((uint)index);

// TODO: Work around playlist bug that doesn't continue playing after a switch; remove later
BackgroundMediaPlayer.Current.Play();
}
catch
{
// ignored
}
// TODO: Work around playlist bug that doesn't continue playing after a switch; remove later
BackgroundMediaPlayer.Current.Play();
}

private void ForegroundMessengerOnStartPlayback(object sender, EventArgs eventArgs)
Expand Down
21 changes: 21 additions & 0 deletions Windows/Audiotica.Windows/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@
<converters:ImageSourceConverter x:Key="ImageSourceConverter" />
<converters:UpperCaseConverter x:Key="UpperCaseConverter" />
<converters:UniformSpacingConverter x:Key="UniformSpacingConverter" />
<converters:NotConverter x:Key="NotConverter" />
<converters:IntToThemeConverter x:Key="IntToThemeConverter" />
<converters:IntToBoolConverter x:Key="IntToBoolConverter" />

<converters:ContentConverter x:Key="SingleMultiSelectionModeConverter">
<converters:ContentConverter.TrueContent>
<ListViewSelectionMode>Multiple</ListViewSelectionMode>
</converters:ContentConverter.TrueContent>
<converters:ContentConverter.FalseContent>
<ListViewSelectionMode>Single</ListViewSelectionMode>
</converters:ContentConverter.FalseContent>
</converters:ContentConverter>

<converters:ContentConverter x:Key="NoneMultiSelectionModeConverter">
<converters:ContentConverter.TrueContent>
<ListViewSelectionMode>Multiple</ListViewSelectionMode>
</converters:ContentConverter.TrueContent>
<converters:ContentConverter.FalseContent>
<ListViewSelectionMode>None</ListViewSelectionMode>
</converters:ContentConverter.FalseContent>
</converters:ContentConverter>

<SolidColorBrush x:Name="SubtleTextBrush" Color="{ThemeResource SystemBaseMediumColor}" />

Expand Down
Loading

0 comments on commit c5d3839

Please sign in to comment.