Skip to content

Commit

Permalink
Merge pull request #84 from Wolfteam/feature/playlists_grid
Browse files Browse the repository at this point in the history
Feature/playlists grid
  • Loading branch information
Wolfteam authored Jan 10, 2021
2 parents ba8ef31 + ede57a5 commit 14c1a30
Show file tree
Hide file tree
Showing 72 changed files with 1,727 additions and 568 deletions.
4 changes: 2 additions & 2 deletions CastIt.Application/CastIt.Application.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

<ItemGroup>
<PackageReference Include="HtmlAgilityPack" Version="1.11.29" />
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="4.0.0" />
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.0.0" />
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="4.1.0" />
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Management" Version="5.0.0" />
Expand Down
2 changes: 1 addition & 1 deletion CastIt.Application/FFmpeg/FFmpegService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public string GetThumbnail(string mrl)
}

var filename = Path.GetFileName(mrl);
var thumbnailPath = _fileService.GetThumbnailFilePath(filename, 0);
var thumbnailPath = _fileService.GetFirstThumbnailFilePath(filename);
if (File.Exists(thumbnailPath))
{
return thumbnailPath;
Expand Down
3 changes: 3 additions & 0 deletions CastIt.Application/FilePaths/FileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ public string GetSubTitleFolder()
return CreateDirectory(basePath, SubTitlesFolderName);
}

public string GetFirstThumbnailFilePath(string filename)
=> GetThumbnailFilePath(filename, 0);

public string GetThumbnailFilePath(string filename, long second)
{
return Path.Combine(GetPreviewsPath(), $"{filename}_{second:D2}.jpg");
Expand Down
2 changes: 2 additions & 0 deletions CastIt.Application/Interfaces/IFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ public interface IFileService : ICommonFileService

string GetPreviewsPath();

string GetFirstThumbnailFilePath(string filename);

string GetThumbnailFilePath(string filename, long second);

string GetPreviewThumbnailFilePath(string filename);
Expand Down
39 changes: 23 additions & 16 deletions CastIt.Application/Youtube/YoutubeUrlDecoder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -455,27 +455,29 @@ private Dictionary<int, string> GetVideoQualities(string body)
_logger.LogInformation($"{nameof(GetVideoQualities)}: Getting video qualities...");
var formatPattern = @"(\\""formats\\"":\[.*?])";
var formatMatch = Regex.Match(body, formatPattern);

if (formatMatch.Length == 0)
{
_logger.LogInformation($"{nameof(GetVideoQualities)}: Couldn't retrieve formats, checking if we have adaptiveFormats...");
formatPattern = @"(\\""adaptiveFormats\\"":\[.*?])";
_logger.LogInformation(
$"{nameof(GetVideoQualities)}: Couldn't retrieve formats, " +
"checking if the formats is not between slashes using the format keyword...");
formatPattern = @"(\""formats\"":\[.*?])";
formatMatch = Regex.Match(body, formatPattern);
}

if (formatMatch.Length == 0)
{
_logger.LogInformation(
$"{nameof(GetVideoQualities)}: Couldn't retrieve formats, " +
"checking if the formats is not between slashes using the format keyword...");
formatPattern = @"(\""formats\"":\[.*?])";
$"{nameof(GetVideoQualities)}: Couldn't retrieve formats, checking if we have adaptive formats...");
formatPattern = @"(\\""adaptiveFormats\\"":\[.*?])";
formatMatch = Regex.Match(body, formatPattern);
}

if (formatMatch.Length == 0)
{
_logger.LogInformation(
$"{nameof(GetVideoQualities)}: Couldn't retrieve formats, " +
"checking if the formats is not between slashes using the adaptiveFormats keyword...");
$"{nameof(GetVideoQualities)}: Couldn't retrieve adaptive formats, " +
"checking if the formats is not between slashes using the format keyword...");
formatPattern = @"(\""adaptiveFormats\"":\[.*?])";
formatMatch = Regex.Match(body, formatPattern);
}
Expand All @@ -491,24 +493,29 @@ private Dictionary<int, string> GetVideoQualities(string body)
string heightPatternA = @"(?<=\\""height\\"":).+?(?=,)";
string heightPatternB = @"(?<=\""height\"":).+?(?=,)";
var streams = Regex.Matches(streamMap, "{(.*?)}").AsQueryable().OfType<Match>().ToList();
var qualities = streams.ToDictionary(k =>

var qualitiesDictionary = new Dictionary<int, string>();
foreach (var stream in streams)
{
var val = Regex.Match(k.ToString(), heightPatternA).Value;
var match = stream.Value;
var val = Regex.Match(match, heightPatternA).Value;
if (string.IsNullOrEmpty(val))
{
_logger.LogInformation($"Couldn't retrieve height, trying now without backslashes in the pattern");
val = Regex.Match(k.ToString(), heightPatternB).Value;
_logger.LogInformation("Couldn't retrieve height, trying now without backslashes in the pattern");
val = Regex.Match(match, heightPatternB).Value;
}

if (string.IsNullOrEmpty(val))
{
_logger.LogWarning($"Couldn't retrieve height from = {k}");
_logger.LogWarning($"Couldn't retrieve height from = {match}");
}

return int.Parse(string.IsNullOrEmpty(val) ? "-1" : val);
}, v => v.ToString());

var qualitiesDictionary = qualities.Where(kvp => kvp.Key > 0).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
int quality = int.Parse(string.IsNullOrEmpty(val) ? "-1" : val);
if (!qualitiesDictionary.ContainsKey(quality) && quality > 0)
{
qualitiesDictionary.Add(quality, match);
}
}

_logger.LogInformation($"{nameof(GetVideoQualities)}: Got = {qualitiesDictionary.Count} video qualities");

Expand Down
4 changes: 2 additions & 2 deletions CastIt.Cli/CastIt.Cli.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

<ItemGroup>
<PackageReference Include="ConsoleTables" Version="2.4.2" />
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="3.0.0" />
<PackageReference Include="McMaster.Extensions.Hosting.CommandLine" Version="3.0.0" />
<PackageReference Include="McMaster.Extensions.CommandLineUtils" Version="3.1.0" />
<PackageReference Include="McMaster.Extensions.Hosting.CommandLine" Version="3.1.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Refit.HttpClientFactory" Version="5.2.4" />
Expand Down
10 changes: 8 additions & 2 deletions CastIt.Domain/Models/FFmpeg/Info/FileInfoStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,18 @@ public class FileInfoStream
[JsonProperty(PropertyName = "sample_rate")]
public long SampleRate { get; set; }

[JsonProperty(PropertyName = "nb_frames")]
public long NumberOfFrames { get; set; }

[JsonProperty(PropertyName = "avg_frame_rate")]
public string AverageFrameRate { get; set; }

[JsonProperty(PropertyName = "tags")]
public FileInfoTag Tag { get; set; }

//The CodecType in an audio returns may return video if the stream is a png img
//The CodecType in an audio file may return video if the stream is a png img
public bool IsVideo
=> CodecType == "video" && Level > 0;
=> CodecType == "video" && Level != 0 && (NumberOfFrames > 1 || AverageFrameRate != "0/0");

public bool IsAudio
=> CodecType == "audio";
Expand Down
1 change: 1 addition & 0 deletions CastIt.Infrastructure/Interfaces/IAppSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public interface IAppSettingsService
bool EnableHardwareAcceleration { get; set; }
bool MinimizeToTray { get; set; }
bool ShowPlayListTotalDuration { get; set; }
bool UseGridViewForPlayLists { get; set; }

SubtitleFgColorType CurrentSubtitleFgColor { get; set; }
SubtitleBgColorType CurrentSubtitleBgColor { get; set; }
Expand Down
2 changes: 2 additions & 0 deletions CastIt.Infrastructure/Models/AppSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ internal class AppSettings
public bool EnableHardwareAcceleration { get; set; }
public bool MinimizeToTray { get; set; }
public bool ShowPlayListTotalDuration { get; set; }
public bool UseGridViewForPlayLists { get; set; }

public SubtitleFgColorType CurrentSubtitleFgColor { get; set; }
public SubtitleBgColorType CurrentSubtitleBgColor { get; set; }
public SubtitleFontScaleType CurrentSubtitleFontScale { get; set; }
Expand Down
6 changes: 6 additions & 0 deletions CastIt.Infrastructure/Services/AppSettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ public bool ShowPlayListTotalDuration
set => _appSettings.ShowPlayListTotalDuration = value;
}

public bool UseGridViewForPlayLists
{
get => _appSettings.UseGridViewForPlayLists;
set => _appSettings.UseGridViewForPlayLists = value;
}

public SubtitleFgColorType CurrentSubtitleFgColor
{
get => _appSettings.CurrentSubtitleFgColor;
Expand Down
3 changes: 3 additions & 0 deletions CastIt/App.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
<converters:FileOptionsMultiConverter x:Key="FileOptionsMultiConverter" />
<converters:InverseBooleanToVisibilityConverter x:Key="InverseBooleanToVisibilityConverter" />
<converters:BooleanOrConverter x:Key="BooleanOrConverter" />
<converters:PlayListCardItemMultiConverter x:Key="PlayListCardItemMultiConverter" />
<converters:NumberComparerToBooleanConverter x:Key="EqualToBooleanConverter" Equal="True" />
<converters:NumberComparerToBooleanConverter x:Key="GreaterThanToBooleanConverter" GreaterThan="True" />

<SolidColorBrush x:Key="FontColorOnDarkBackgroundBrush" Color="White" />
<BitmapImage x:Key="NoImgFound" UriSource="/Resources/NoImg.png" />
Expand Down
6 changes: 3 additions & 3 deletions CastIt/CastIt.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="Dragablz.NetCore" Version="0.3.3" />
<PackageReference Include="FluentMigrator" Version="3.2.10" />
<PackageReference Include="FluentMigrator.Runner" Version="3.2.10" />
<PackageReference Include="FluentMigrator" Version="3.2.11" />
<PackageReference Include="FluentMigrator.Runner" Version="3.2.11" />
<PackageReference Include="FreeSql.Provider.Sqlite" Version="2.0.105" />
<PackageReference Include="MaterialDesignThemes" Version="3.2.0-ci1901" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.31" />
<PackageReference Include="MvvmCross.Platforms.Wpf" Version="7.1.2" />
<PackageReference Include="MvvmCross.Plugin.Messenger" Version="7.1.2" />
<PackageReference Include="MvvmCross.Plugin.ResxLocalization" Version="7.1.2" />
Expand Down
82 changes: 54 additions & 28 deletions CastIt/Common/Behaviours/MultiSelectionBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,51 @@ namespace CastIt.Common.Behaviours
/// </summary>
public class MultiSelectionBehavior : Behavior<ListBox>
{
private bool _isUpdatingTarget;
private bool _isUpdatingSource;

public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.Register("SelectedItems", typeof(IList), typeof(MultiSelectionBehavior), new UIPropertyMetadata(null, SelectedItemsChanged));

public IList SelectedItems
{
get => (IList)GetValue(SelectedItemsProperty);
set => SetValue(SelectedItemsProperty, value);
}

protected override void OnAttached()
{
AssociatedObject.Unloaded += OnUnloaded;
base.OnAttached();
if (SelectedItems != null)
if (SelectedItems == null)
return;
AssociatedObject.SelectedItems.Clear();
foreach (var item in SelectedItems)
{
AssociatedObject.SelectedItems.Clear();
foreach (var item in SelectedItems)
{
AssociatedObject.SelectedItems.Add(item);
}
AssociatedObject.SelectedItems.Add(item);
}
}

public IList SelectedItems
private void OnUnloaded(object sender, RoutedEventArgs e)
{
get { return (IList)GetValue(SelectedItemsProperty); }
set { SetValue(SelectedItemsProperty, value); }
OnDetaching();
}

public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.Register("SelectedItems", typeof(IList), typeof(MultiSelectionBehavior), new UIPropertyMetadata(null, SelectedItemsChanged));
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.Unloaded -= OnUnloaded;
AssociatedObject.SelectionChanged -= ListBoxSelectionChanged;

if (AssociatedObject.SelectedItems is INotifyCollectionChanged val)
{
val.CollectionChanged -= SourceCollectionChanged;
}
}

private static void SelectedItemsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
var behavior = o as MultiSelectionBehavior;
if (behavior == null)
if (!(o is MultiSelectionBehavior behavior))
return;

var oldValue = e.OldValue as INotifyCollectionChanged;
Expand All @@ -47,29 +66,35 @@ private static void SelectedItemsChanged(DependencyObject o, DependencyPropertyC
oldValue.CollectionChanged -= behavior.SourceCollectionChanged;
behavior.AssociatedObject.SelectionChanged -= behavior.ListBoxSelectionChanged;
}
if (newValue != null)
{
behavior.AssociatedObject.SelectedItems.Clear();
foreach (var item in (IEnumerable)newValue)
{
behavior.AssociatedObject.SelectedItems.Add(item);
}

behavior.AssociatedObject.SelectionChanged += behavior.ListBoxSelectionChanged;
newValue.CollectionChanged += behavior.SourceCollectionChanged;
if (newValue == null)
return;

behavior.AssociatedObject.SelectedItems.Clear();
foreach (var item in (IEnumerable)newValue)
{
behavior.AssociatedObject.SelectedItems.Add(item);
}
}

private bool _isUpdatingTarget;
private bool _isUpdatingSource;
behavior.AssociatedObject.SelectionChanged += behavior.ListBoxSelectionChanged;
newValue.CollectionChanged += behavior.SourceCollectionChanged;
}

void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
private void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (_isUpdatingSource)
return;

if (AssociatedObject is null)
{
System.Diagnostics.Debug.WriteLine("Collection associated object is null");
return;
}

try
{
//TODO: TRY TO FIX THE CRASH WHEN SWITCHING VIEWS
System.Diagnostics.Debug.WriteLine("Collection changed started....");
_isUpdatingTarget = true;

if (e.OldItems != null)
Expand All @@ -96,6 +121,7 @@ void SourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
finally
{
_isUpdatingTarget = false;
System.Diagnostics.Debug.WriteLine("Collection changed completed");
}
}

Expand All @@ -111,7 +137,7 @@ private void ListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
try
{
_isUpdatingSource = true;

System.Diagnostics.Debug.WriteLine("Selection changed started....");
foreach (var item in e.RemovedItems)
{
selectedItems.Remove(item);
Expand All @@ -125,8 +151,8 @@ private void ListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
finally
{
_isUpdatingSource = false;
System.Diagnostics.Debug.WriteLine("Selection changed completed");
}
}

}
}
43 changes: 43 additions & 0 deletions CastIt/Common/Converters/NumberComparerToBooleanConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Globalization;
using System.Windows.Data;

namespace CastIt.Common.Converters
{
public class NumberComparerToBooleanConverter : IValueConverter
{
public bool GreaterThan { get; set; }
public bool GreaterThanOrEqual { get; set; }
public bool Equal { get; set; }
public bool LessThan { get; set; }
public bool LessThanOrEqual { get; set; }

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var currentItems = System.Convert.ToInt32(value);
var expected = System.Convert.ToInt32(parameter);

if (GreaterThan)
return currentItems > expected;

if (GreaterThanOrEqual)
return currentItems >= expected;

if (Equal)
return currentItems == expected;

if (LessThan)
return currentItems < expected;

if (LessThanOrEqual)
return currentItems <= expected;

throw new InvalidOperationException("You need to set one of the converters properties");
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Loading

0 comments on commit 14c1a30

Please sign in to comment.