twitch vod downloading done
ffmpeg essentials fix Project reorganized git lfs ffmpeg removed ffmpeg added
This commit is contained in:
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*.exe filter=lfs diff=lfs merge=lfs -text
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using VDownload.Common.Models;
|
|
||||||
|
|
||||||
namespace VDownload.Common
|
|
||||||
{
|
|
||||||
public abstract class Playlist : ObservableObject, IEnumerable<Video>
|
|
||||||
{
|
|
||||||
public IEnumerator<Video> GetEnumerator()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using VDownload.Common.Models;
|
|
||||||
|
|
||||||
namespace VDownload.Common.Services
|
|
||||||
{
|
|
||||||
public interface ISourceSearchService
|
|
||||||
{
|
|
||||||
Task<Video> SearchVideo(string url);
|
|
||||||
Task<Playlist> SearchPlaylist(string url, int maxVideoCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.Common.Models
|
|
||||||
{
|
|
||||||
public abstract partial class Video : ObservableObject
|
|
||||||
{
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected string _title;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected string _description;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected string _author;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected DateTime _publishDate;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected TimeSpan _duration;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected int _viewCount;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected string? _thumbnailUrl;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected ObservableCollection<VideoStream> _streams;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected string _url;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected Source _source;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region CONSTRUCTORS
|
|
||||||
|
|
||||||
protected Video()
|
|
||||||
{
|
|
||||||
_streams = new ObservableCollection<VideoStream>();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.Common
|
|
||||||
{
|
|
||||||
public abstract partial class VideoStream : ObservableObject
|
|
||||||
{
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
protected string _streamIdentifier;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private int _width;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,147 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="AuthenticationButtonSignIn.Value" xml:space="preserve">
|
||||||
|
<value>Sign in</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthenticationButtonSignOut.Value" xml:space="preserve">
|
||||||
|
<value>Sign out</value>
|
||||||
|
</data>
|
||||||
|
<data name="AuthenticationDescriptionLoading.Value" xml:space="preserve">
|
||||||
|
<value>Loading...</value>
|
||||||
|
</data>
|
||||||
|
<data name="Header.Text" xml:space="preserve">
|
||||||
|
<value>Authentication</value>
|
||||||
|
</data>
|
||||||
|
<data name="TwitchAuthenticationDescriptionAuthenticated" xml:space="preserve">
|
||||||
|
<value>Signed in as {0}. Expiration date: {1}</value>
|
||||||
|
</data>
|
||||||
|
<data name="TwitchAuthenticationDescriptionAuthenticationInvalid" xml:space="preserve">
|
||||||
|
<value>Token expired or is invalid. Please log in again</value>
|
||||||
|
</data>
|
||||||
|
<data name="TwitchAuthenticationDescriptionNotAuthenticated" xml:space="preserve">
|
||||||
|
<value>You are not authenticated. Please sign in</value>
|
||||||
|
</data>
|
||||||
|
<data name="TwitchAuthenticationDialogTitle" xml:space="preserve">
|
||||||
|
<value>Twitch authentication error</value>
|
||||||
|
</data>
|
||||||
|
<data name="TwitchAuthenticationWindowTitle" xml:space="preserve">
|
||||||
|
<value>Sign in to Twitch</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -117,7 +117,10 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="Main_OptionBar_PlaylistSearchTB.PlaceholderText" xml:space="preserve">
|
<data name="AuthenticationNavigationViewItem" xml:space="preserve">
|
||||||
<value>Test</value>
|
<value>Authentication</value>
|
||||||
|
</data>
|
||||||
|
<data name="HomeNavigationViewItem" xml:space="preserve">
|
||||||
|
<value>Home</value>
|
||||||
</data>
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="MediaTypeOnlyAudio.Text" xml:space="preserve">
|
||||||
|
<value>Only audio</value>
|
||||||
|
</data>
|
||||||
|
<data name="MediaTypeOnlyVideo.Text" xml:space="preserve">
|
||||||
|
<value>Only video</value>
|
||||||
|
</data>
|
||||||
|
<data name="MediaTypeOriginal.Text" xml:space="preserve">
|
||||||
|
<value>Original</value>
|
||||||
|
</data>
|
||||||
|
<data name="StatusCancelled.Text" xml:space="preserve">
|
||||||
|
<value>Cancelled</value>
|
||||||
|
</data>
|
||||||
|
<data name="StatusDone.Text" xml:space="preserve">
|
||||||
|
<value>Done</value>
|
||||||
|
</data>
|
||||||
|
<data name="StatusDownloading.Text" xml:space="preserve">
|
||||||
|
<value>Downloading</value>
|
||||||
|
</data>
|
||||||
|
<data name="StatusError.Text" xml:space="preserve">
|
||||||
|
<value>Error</value>
|
||||||
|
</data>
|
||||||
|
<data name="StatusFinalizing.Text" xml:space="preserve">
|
||||||
|
<value>Finalizing</value>
|
||||||
|
</data>
|
||||||
|
<data name="StatusIdle.Text" xml:space="preserve">
|
||||||
|
<value>Idle</value>
|
||||||
|
</data>
|
||||||
|
<data name="StatusInitializing.Text" xml:space="preserve">
|
||||||
|
<value>Initializing</value>
|
||||||
|
</data>
|
||||||
|
<data name="StatusProcessing.Text" xml:space="preserve">
|
||||||
|
<value>Processing</value>
|
||||||
|
</data>
|
||||||
|
<data name="StatusQueued.Text" xml:space="preserve">
|
||||||
|
<value>Queued</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="CreateAndStartButton.Content" xml:space="preserve">
|
||||||
|
<value>Create download task and start</value>
|
||||||
|
</data>
|
||||||
|
<data name="CreateButton.Content" xml:space="preserve">
|
||||||
|
<value>Create download task</value>
|
||||||
|
</data>
|
||||||
|
<data name="DirectorySettingsCard.Header" xml:space="preserve">
|
||||||
|
<value>Directory</value>
|
||||||
|
</data>
|
||||||
|
<data name="DirectorySettingsCardButton.Content" xml:space="preserve">
|
||||||
|
<value>Browse</value>
|
||||||
|
</data>
|
||||||
|
<data name="FilenameSettingsCard.Header" xml:space="preserve">
|
||||||
|
<value>Filename</value>
|
||||||
|
</data>
|
||||||
|
<data name="FileOptionsHeader.Text" xml:space="preserve">
|
||||||
|
<value>File options</value>
|
||||||
|
</data>
|
||||||
|
<data name="FileTypeSettingsCard.Description" xml:space="preserve">
|
||||||
|
<value>If original video is not in selected type, it will be converted</value>
|
||||||
|
</data>
|
||||||
|
<data name="FileTypeSettingsCard.Header" xml:space="preserve">
|
||||||
|
<value>File type</value>
|
||||||
|
</data>
|
||||||
|
<data name="MediaOptionsHeader.Text" xml:space="preserve">
|
||||||
|
<value>Media options</value>
|
||||||
|
</data>
|
||||||
|
<data name="MediaTypeOnlyAudio.Text" xml:space="preserve">
|
||||||
|
<value>Only audio</value>
|
||||||
|
</data>
|
||||||
|
<data name="MediaTypeOnlyVideo.Text" xml:space="preserve">
|
||||||
|
<value>Only video</value>
|
||||||
|
</data>
|
||||||
|
<data name="MediaTypeOriginal.Text" xml:space="preserve">
|
||||||
|
<value>Original</value>
|
||||||
|
</data>
|
||||||
|
<data name="MediaTypeSettingsCard.Header" xml:space="preserve">
|
||||||
|
<value>Media type</value>
|
||||||
|
</data>
|
||||||
|
<data name="QualitySettingsCard.Header" xml:space="preserve">
|
||||||
|
<value>Quality</value>
|
||||||
|
</data>
|
||||||
|
<data name="TrimEndSettingsCard.Header" xml:space="preserve">
|
||||||
|
<value>End at</value>
|
||||||
|
</data>
|
||||||
|
<data name="TrimSettingsGroup.Header" xml:space="preserve">
|
||||||
|
<value>Trim</value>
|
||||||
|
</data>
|
||||||
|
<data name="TrimStartSettingsCard.Header" xml:space="preserve">
|
||||||
|
<value>Start at</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,160 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="OptionBarDownloadAll.Label" xml:space="preserve">
|
||||||
|
<value>Download all</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarDownloadAll.Width" xml:space="preserve">
|
||||||
|
<value>100</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarLoadSubscription.Label" xml:space="preserve">
|
||||||
|
<value>Load from subscriptions</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarLoadSubscription.Width" xml:space="preserve">
|
||||||
|
<value>150</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarMessageLoading" xml:space="preserve">
|
||||||
|
<value>Loading...</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarPlaylistSearch.Label" xml:space="preserve">
|
||||||
|
<value>Playlist search</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarPlaylistSearch.Width" xml:space="preserve">
|
||||||
|
<value>100</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarPlaylistSearchContentNumberBox.ToolTipService.ToolTip" xml:space="preserve">
|
||||||
|
<value>Number of videos to get from playlist
|
||||||
|
0 = Get all</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarPlaylistSearchContentTextBox.PlaceholderText" xml:space="preserve">
|
||||||
|
<value>Playlist URL</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarSearchButton.Content" xml:space="preserve">
|
||||||
|
<value>Search</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarVideoSearch.Label" xml:space="preserve">
|
||||||
|
<value>Video search</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarVideoSearch.Width" xml:space="preserve">
|
||||||
|
<value>100</value>
|
||||||
|
</data>
|
||||||
|
<data name="OptionBarVideoSearchContentTextBox.PlaceholderText" xml:space="preserve">
|
||||||
|
<value>Video URL</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<data name="Author" xml:space="preserve">
|
||||||
|
<value>Author</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message" xml:space="preserve">
|
||||||
|
<value>Message</value>
|
||||||
|
</data>
|
||||||
|
<data name="OnSuccessfulTitle" xml:space="preserve">
|
||||||
|
<value>Task ended successfully</value>
|
||||||
|
</data>
|
||||||
|
<data name="OnUnsuccessfulTitle" xml:space="preserve">
|
||||||
|
<value>Task ended unsuccessfully</value>
|
||||||
|
</data>
|
||||||
|
<data name="Title" xml:space="preserve">
|
||||||
|
<value>Title</value>
|
||||||
|
</data>
|
||||||
|
</root>
|
||||||
@@ -2,10 +2,10 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||||
<RootNamespace>VDownload.Tasks</RootNamespace>
|
<RootNamespace>VDownload.Core.Strings</RootNamespace>
|
||||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||||
<UseWinUI>true</UseWinUI>
|
<UseWinUI>true</UseWinUI>
|
||||||
<UseRidGraph>true</UseRidGraph>
|
<UseRidGraph>true</UseRidGraph>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\VDownload.Common\VDownload.Common.csproj" />
|
<PRIResource Update="Strings\en-US\BaseViewResources.resw">
|
||||||
|
<Generator></Generator>
|
||||||
|
</PRIResource>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
229
VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs
Normal file
229
VDownload.Core/VDownload.Core.Tasks/DownloadTask.cs
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using VDownload.Models;
|
||||||
|
using VDownload.Services.Utility.FFmpeg;
|
||||||
|
using VDownload.Services.Data.Configuration;
|
||||||
|
using VDownload.Services.Data.Settings;
|
||||||
|
using Windows.System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Windows.Storage;
|
||||||
|
using System.IO;
|
||||||
|
using VDownload.Services.UI.Notifications;
|
||||||
|
using VDownload.Services.UI.StringResources;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace VDownload.Core.Tasks
|
||||||
|
{
|
||||||
|
public partial class DownloadTask : ObservableObject
|
||||||
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
protected readonly IConfigurationService _configurationService;
|
||||||
|
protected readonly ISettingsService _settingsService;
|
||||||
|
protected readonly IFFmpegService _ffmpegService;
|
||||||
|
protected readonly IStringResourcesService _stringResourcesService;
|
||||||
|
protected readonly INotificationsService _notificationsService;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region FIELDS
|
||||||
|
|
||||||
|
private readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread();
|
||||||
|
|
||||||
|
private CancellationTokenSource? _cancellationTokenSource;
|
||||||
|
|
||||||
|
private Task _downloadTask;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected Guid _id;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected Video _video;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected VideoDownloadOptions _downloadOptions;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected DownloadTaskStatus _status;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected DateTime _createDate;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected double _progress;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected string? _error;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
internal DownloadTask(Video video, VideoDownloadOptions downloadOptions, IConfigurationService configurationService, ISettingsService settingsService, IFFmpegService ffmpegService, IStringResourcesService stringResourcesService, INotificationsService notificationsService)
|
||||||
|
{
|
||||||
|
_configurationService = configurationService;
|
||||||
|
_settingsService = settingsService;
|
||||||
|
_ffmpegService = ffmpegService;
|
||||||
|
_stringResourcesService = stringResourcesService;
|
||||||
|
_notificationsService = notificationsService;
|
||||||
|
|
||||||
|
_video = video;
|
||||||
|
_downloadOptions = downloadOptions;
|
||||||
|
_id = Guid.NewGuid();
|
||||||
|
_status = DownloadTaskStatus.Idle;
|
||||||
|
_createDate = DateTime.Now;
|
||||||
|
_progress = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public void Enqueue()
|
||||||
|
{
|
||||||
|
DownloadTaskStatus[] statuses =
|
||||||
|
[
|
||||||
|
DownloadTaskStatus.Idle,
|
||||||
|
DownloadTaskStatus.EndedUnsuccessfully,
|
||||||
|
DownloadTaskStatus.EndedSuccessfully,
|
||||||
|
DownloadTaskStatus.EndedCancelled,
|
||||||
|
];
|
||||||
|
if (statuses.Contains(Status))
|
||||||
|
{
|
||||||
|
Status = DownloadTaskStatus.Queued;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Start()
|
||||||
|
{
|
||||||
|
_cancellationTokenSource = new CancellationTokenSource();
|
||||||
|
|
||||||
|
UpdateStatusWithDispatcher(DownloadTaskStatus.Initializing);
|
||||||
|
|
||||||
|
_downloadTask = Download();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Cancel()
|
||||||
|
{
|
||||||
|
if (_cancellationTokenSource is not null)
|
||||||
|
{
|
||||||
|
_cancellationTokenSource.Cancel();
|
||||||
|
await _downloadTask;
|
||||||
|
_cancellationTokenSource.Dispose();
|
||||||
|
_cancellationTokenSource = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
private async Task Download()
|
||||||
|
{
|
||||||
|
CancellationToken token = _cancellationTokenSource.Token;
|
||||||
|
|
||||||
|
await _settingsService.Load();
|
||||||
|
|
||||||
|
string tempDirectory = $"{_settingsService.Data.Common.TempDirectory}\\{_configurationService.Common.Path.Temp.TasksDirectory}\\{_id}";
|
||||||
|
Directory.CreateDirectory(tempDirectory);
|
||||||
|
|
||||||
|
List<string> content = new List<string>()
|
||||||
|
{
|
||||||
|
$"{_stringResourcesService.NotificationsResources.Get("Title")}: {Video.Title}",
|
||||||
|
$"{_stringResourcesService.NotificationsResources.Get("Author")}: {Video.Author}"
|
||||||
|
};
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IProgress<double> onProgressDownloading = new Progress<double>((value) =>
|
||||||
|
{
|
||||||
|
UpdateStatusWithDispatcher(DownloadTaskStatus.Downloading);
|
||||||
|
UpdateProgressWithDispatcher(value);
|
||||||
|
});
|
||||||
|
|
||||||
|
VideoStreamDownloadResult downloadResult = await DownloadOptions.SelectedStream.Download(tempDirectory, onProgressDownloading, token, DownloadOptions.TrimStart, DownloadOptions.TrimEnd);
|
||||||
|
|
||||||
|
Action<double> onProgressProcessing = (value) =>
|
||||||
|
{
|
||||||
|
UpdateStatusWithDispatcher(DownloadTaskStatus.Processing);
|
||||||
|
UpdateProgressWithDispatcher(value);
|
||||||
|
};
|
||||||
|
string outputPath = $"{tempDirectory}\\processed.{DownloadOptions.Extension}";
|
||||||
|
|
||||||
|
FFmpegBuilder ffmpegBuilder = _ffmpegService.CreateBuilder();
|
||||||
|
if (downloadResult.NewTrimStart != TimeSpan.Zero)
|
||||||
|
{
|
||||||
|
ffmpegBuilder.TrimStart(downloadResult.NewTrimStart);
|
||||||
|
}
|
||||||
|
if (downloadResult.NewTrimEnd != downloadResult.NewDuration)
|
||||||
|
{
|
||||||
|
ffmpegBuilder.TrimEnd(downloadResult.NewTrimEnd);
|
||||||
|
}
|
||||||
|
ffmpegBuilder.SetMediaType(DownloadOptions.MediaType)
|
||||||
|
.JoinCancellationToken(token)
|
||||||
|
.JoinProgressReporter(onProgressProcessing, downloadResult.NewDuration);
|
||||||
|
await ffmpegBuilder.RunAsync(downloadResult.File, outputPath);
|
||||||
|
|
||||||
|
UpdateStatusWithDispatcher(DownloadTaskStatus.Finalizing);
|
||||||
|
|
||||||
|
string destination = $"{DownloadOptions.Directory}\\{DownloadOptions.Filename}.{DownloadOptions.Extension}";
|
||||||
|
File.Copy(outputPath, destination, true);
|
||||||
|
|
||||||
|
UpdateStatusWithDispatcher(DownloadTaskStatus.EndedSuccessfully);
|
||||||
|
|
||||||
|
if (_settingsService.Data.Common.Notifications.OnSuccessful)
|
||||||
|
{
|
||||||
|
string title = _stringResourcesService.NotificationsResources.Get("OnSuccessfulTitle");
|
||||||
|
_notificationsService.SendNotification(title, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException)
|
||||||
|
{
|
||||||
|
UpdateStatusWithDispatcher(DownloadTaskStatus.EndedCancelled);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
UpdateErrorWithDispatcher(ex.Message);
|
||||||
|
UpdateStatusWithDispatcher(DownloadTaskStatus.EndedUnsuccessfully);
|
||||||
|
|
||||||
|
if (_settingsService.Data.Common.Notifications.OnUnsuccessful)
|
||||||
|
{
|
||||||
|
string title = _stringResourcesService.NotificationsResources.Get("OnSuccessfulTitle");
|
||||||
|
content.Add($"{_stringResourcesService.NotificationsResources.Get("Message")}: {ex.Message}");
|
||||||
|
_notificationsService.SendNotification(title, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (Status != DownloadTaskStatus.EndedUnsuccessfully || _settingsService.Data.Common.DeleteTempOnError)
|
||||||
|
{
|
||||||
|
Directory.Delete(tempDirectory, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateStatusWithDispatcher(DownloadTaskStatus status) => _dispatcherQueue.TryEnqueue(() => Status = status);
|
||||||
|
|
||||||
|
private void UpdateProgressWithDispatcher(double progress) => _dispatcherQueue.TryEnqueue(() => Progress = progress);
|
||||||
|
|
||||||
|
private void UpdateErrorWithDispatcher(string message) => _dispatcherQueue.TryEnqueue(() => Error = message);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Models;
|
||||||
|
using VDownload.Services.Data.Configuration;
|
||||||
|
using VDownload.Services.Data.Settings;
|
||||||
|
using VDownload.Services.UI.Notifications;
|
||||||
|
using VDownload.Services.UI.StringResources;
|
||||||
|
using VDownload.Services.Utility.FFmpeg;
|
||||||
|
|
||||||
|
namespace VDownload.Core.Tasks
|
||||||
|
{
|
||||||
|
public interface IDownloadTaskFactoryService
|
||||||
|
{
|
||||||
|
DownloadTask Create(Video video, VideoDownloadOptions downloadOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class DownloadTaskFactoryService : IDownloadTaskFactoryService
|
||||||
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
protected readonly IConfigurationService _configurationService;
|
||||||
|
protected readonly ISettingsService _settingsService;
|
||||||
|
protected readonly IFFmpegService _ffmpegService;
|
||||||
|
protected readonly IStringResourcesService _stringResourcesService;
|
||||||
|
protected readonly INotificationsService _notificationsService;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public DownloadTaskFactoryService(IConfigurationService configurationService, ISettingsService settingsService, IFFmpegService ffmpegService, IStringResourcesService stringResourcesService, INotificationsService notificationsService)
|
||||||
|
{
|
||||||
|
_configurationService = configurationService;
|
||||||
|
_settingsService = settingsService;
|
||||||
|
_ffmpegService = ffmpegService;
|
||||||
|
_stringResourcesService = stringResourcesService;
|
||||||
|
_notificationsService = notificationsService;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public DownloadTask Create(Video video, VideoDownloadOptions downloadOptions)
|
||||||
|
{
|
||||||
|
return new DownloadTask(video, downloadOptions, _configurationService, _settingsService, _ffmpegService, _stringResourcesService, _notificationsService);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
168
VDownload.Core/VDownload.Core.Tasks/DownloadTaskManager.cs
Normal file
168
VDownload.Core/VDownload.Core.Tasks/DownloadTaskManager.cs
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Models;
|
||||||
|
using VDownload.Services.Data.Settings;
|
||||||
|
|
||||||
|
namespace VDownload.Core.Tasks
|
||||||
|
{
|
||||||
|
public interface IDownloadTaskManager
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
ReadOnlyObservableCollection<DownloadTask> Tasks { get; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region EVENTS
|
||||||
|
|
||||||
|
event NotifyCollectionChangedEventHandler TaskCollectionChanged;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region METHODS
|
||||||
|
|
||||||
|
DownloadTask AddTask(Video video, VideoDownloadOptions downloadOptions);
|
||||||
|
void RemoveTask(DownloadTask task);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class DownloadTaskManager : IDownloadTaskManager
|
||||||
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
protected readonly IDownloadTaskFactoryService _downloadTaskFactoryService;
|
||||||
|
protected readonly ISettingsService _settingsService;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region FIELDS
|
||||||
|
|
||||||
|
private readonly Thread _taskMonitorThread;
|
||||||
|
|
||||||
|
private readonly ObservableCollection<DownloadTask> _tasksMain;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public ReadOnlyObservableCollection<DownloadTask> Tasks { get; protected set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region EVENTS
|
||||||
|
|
||||||
|
public event NotifyCollectionChangedEventHandler TaskCollectionChanged;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public DownloadTaskManager(IDownloadTaskFactoryService downloadTaskFactoryService, ISettingsService settingsService)
|
||||||
|
{
|
||||||
|
_downloadTaskFactoryService = downloadTaskFactoryService;
|
||||||
|
_settingsService = settingsService;
|
||||||
|
|
||||||
|
_tasksMain = new ObservableCollection<DownloadTask>();
|
||||||
|
_tasksMain.CollectionChanged += Tasks_CollectionChanged;
|
||||||
|
Tasks = new ReadOnlyObservableCollection<DownloadTask>(_tasksMain);
|
||||||
|
|
||||||
|
_taskMonitorThread = new Thread(TaskMonitor)
|
||||||
|
{
|
||||||
|
IsBackground = true
|
||||||
|
};
|
||||||
|
_taskMonitorThread.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public DownloadTask AddTask(Video video, VideoDownloadOptions downloadOptions)
|
||||||
|
{
|
||||||
|
DownloadTask task = _downloadTaskFactoryService.Create(video, downloadOptions);
|
||||||
|
_tasksMain.Add(task);
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveTask(DownloadTask task)
|
||||||
|
{
|
||||||
|
_tasksMain.Remove(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
private async void TaskMonitor()
|
||||||
|
{
|
||||||
|
await _settingsService.Load();
|
||||||
|
|
||||||
|
DownloadTaskStatus[] pendingStatuses =
|
||||||
|
[
|
||||||
|
DownloadTaskStatus.Initializing,
|
||||||
|
DownloadTaskStatus.Downloading,
|
||||||
|
DownloadTaskStatus.Processing,
|
||||||
|
DownloadTaskStatus.Finalizing
|
||||||
|
];
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IEnumerable<DownloadTask> pendingTasks = Tasks.Where(x => pendingStatuses.Contains(x.Status));
|
||||||
|
int freeSlots = _settingsService.Data.Common.MaxNumberOfRunningTasks - pendingTasks.Count();
|
||||||
|
if (freeSlots > 0)
|
||||||
|
{
|
||||||
|
IEnumerable<DownloadTask> queuedTasks = Tasks.Where(x => x.Status == DownloadTaskStatus.Queued).OrderBy(x => x.CreateDate).Take(freeSlots);
|
||||||
|
foreach (DownloadTask queuedTask in queuedTasks)
|
||||||
|
{
|
||||||
|
queuedTask.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
Console.WriteLine("TaskMonitor: Collection locked - skipping");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region EVENT HANDLERS
|
||||||
|
|
||||||
|
private void Tasks_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
TaskCollectionChanged?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Core.Tasks
|
||||||
|
{
|
||||||
|
public class DownloadTaskNotInitializedException : Exception
|
||||||
|
{
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public DownloadTaskNotInitializedException() : base() { }
|
||||||
|
|
||||||
|
public DownloadTaskNotInitializedException(string message) : base(message) { }
|
||||||
|
|
||||||
|
public DownloadTaskNotInitializedException(string message, Exception inner) : base(message, inner) { }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.Common
|
namespace VDownload.Core.Tasks
|
||||||
{
|
{
|
||||||
public enum DownloadTaskStatus
|
public enum DownloadTaskStatus
|
||||||
{
|
{
|
||||||
@@ -14,8 +14,8 @@ namespace VDownload.Common
|
|||||||
EndedCancelled,
|
EndedCancelled,
|
||||||
Queued,
|
Queued,
|
||||||
Initializing,
|
Initializing,
|
||||||
|
Finalizing,
|
||||||
Processing,
|
Processing,
|
||||||
Downloading,
|
Downloading,
|
||||||
Finalizing,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||||
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||||
|
<RootNamespace>VDownload.Core.Tasks</RootNamespace>
|
||||||
|
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||||
|
<UseWinUI>true</UseWinUI>
|
||||||
|
<UseRidGraph>true</UseRidGraph>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\VDownload.Models\VDownload.Models.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.Data\VDownload.Services.Data.Configuration\VDownload.Services.Data.Configuration.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.Data\VDownload.Services.Data.Settings\VDownload.Services.Data.Settings.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.UI\VDownload.Services.UI.Notifications\VDownload.Services.UI.Notifications.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.UI\VDownload.Services.UI.StringResources\VDownload.Services.UI.StringResources.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.Utility\VDownload.Services.Utility.FFmpeg\VDownload.Services.Utility.FFmpeg.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,19 +1,18 @@
|
|||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection.Metadata.Ecma335;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using VDownload.GUI.Services.Dialog;
|
using VDownload.Services.Data.Configuration;
|
||||||
using VDownload.GUI.Services.WebView;
|
using VDownload.Services.UI.Dialogs;
|
||||||
using VDownload.Sources.Twitch;
|
using VDownload.Services.UI.StringResources;
|
||||||
|
using VDownload.Services.UI.WebView;
|
||||||
using VDownload.Sources.Twitch.Authentication;
|
using VDownload.Sources.Twitch.Authentication;
|
||||||
|
|
||||||
namespace VDownload.GUI.ViewModels
|
namespace VDownload.Core.ViewModels.Authentication
|
||||||
{
|
{
|
||||||
public partial class AuthenticationViewModel : ObservableObject
|
public partial class AuthenticationViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
@@ -32,9 +31,11 @@ namespace VDownload.GUI.ViewModels
|
|||||||
|
|
||||||
#region SERVICES
|
#region SERVICES
|
||||||
|
|
||||||
private IDialogService _dialogService;
|
protected readonly IDialogsService _dialogsService;
|
||||||
private IWebViewService _webViewService;
|
protected readonly IWebViewService _webViewService;
|
||||||
private ITwitchAuthenticationService _twitchAuthenticationService;
|
protected readonly IConfigurationService _configurationService;
|
||||||
|
protected readonly IStringResourcesService _stringResourcesService;
|
||||||
|
protected readonly ITwitchAuthenticationService _twitchAuthenticationService;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -43,10 +44,10 @@ namespace VDownload.GUI.ViewModels
|
|||||||
#region PROPERTIES
|
#region PROPERTIES
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _twitchDescription;
|
private AuthenticationButton _twitchButtonState = AuthenticationButton.Loading;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private AuthenticationButton _twitchButtonState;
|
private string _twitchDescription;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -54,13 +55,13 @@ namespace VDownload.GUI.ViewModels
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public AuthenticationViewModel(IDialogService dialogService, IWebViewService webViewService, ITwitchAuthenticationService twitchAuthenticationService)
|
public AuthenticationViewModel(IDialogsService dialogsService, IWebViewService webViewService, IConfigurationService configurationService, IStringResourcesService stringResourcesService, ITwitchAuthenticationService twitchAuthenticationService)
|
||||||
{
|
{
|
||||||
_dialogService = dialogService;
|
_dialogsService = dialogsService;
|
||||||
_webViewService = webViewService;
|
_webViewService = webViewService;
|
||||||
|
_configurationService = configurationService;
|
||||||
|
_stringResourcesService = stringResourcesService;
|
||||||
_twitchAuthenticationService = twitchAuthenticationService;
|
_twitchAuthenticationService = twitchAuthenticationService;
|
||||||
|
|
||||||
TwitchButtonState = AuthenticationButton.Loading;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -69,6 +70,16 @@ namespace VDownload.GUI.ViewModels
|
|||||||
|
|
||||||
#region PUBLIC METHODS
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public async Task Navigation()
|
||||||
|
{
|
||||||
|
List<Task> refreshTasks = new List<Task>
|
||||||
|
{
|
||||||
|
TwitchAuthenticationRefresh()
|
||||||
|
};
|
||||||
|
await Task.WhenAll(refreshTasks);
|
||||||
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public async Task TwitchAuthentication()
|
public async Task TwitchAuthentication()
|
||||||
{
|
{
|
||||||
@@ -81,9 +92,13 @@ namespace VDownload.GUI.ViewModels
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string url = await _webViewService.Show(new Uri(_twitchAuthenticationService.AuthenticationPageUrl), _twitchAuthenticationService.AuthenticationPageClosePredicate, "Twitch authentication");
|
Sources.Twitch.Configuration.Models.Authentication auth = _configurationService.Twitch.Authentication;
|
||||||
|
string authUrl = string.Format(auth.Url, auth.ClientId, auth.RedirectUrl, auth.ResponseType, string.Join(' ', auth.Scopes));
|
||||||
|
|
||||||
Match match = _twitchAuthenticationService.AuthenticationPageRedirectUrlRegex.Match(url);
|
string url = await _webViewService.Show(new Uri(authUrl), (url) => url.StartsWith(auth.RedirectUrl), _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationWindowTitle"));
|
||||||
|
|
||||||
|
Regex regex = new Regex(auth.RedirectUrlRegex);
|
||||||
|
Match match = regex.Match(url);
|
||||||
|
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
{
|
{
|
||||||
@@ -92,22 +107,12 @@ namespace VDownload.GUI.ViewModels
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _dialogService.ShowOk("Twitch authentication error", "An error occured");
|
await _dialogsService.ShowOk(_stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDialogTitle"), "An unknown error occured"); // TODO : Change to string resource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await TwitchAuthenticationRefresh();
|
await TwitchAuthenticationRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
public async Task Navigation()
|
|
||||||
{
|
|
||||||
List<Task> refreshTasks = new List<Task>
|
|
||||||
{
|
|
||||||
TwitchAuthenticationRefresh()
|
|
||||||
};
|
|
||||||
await Task.WhenAll(refreshTasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
@@ -122,7 +127,7 @@ namespace VDownload.GUI.ViewModels
|
|||||||
|
|
||||||
if (token is null)
|
if (token is null)
|
||||||
{
|
{
|
||||||
TwitchDescription = "You are not authenticated. Please sign in";
|
TwitchDescription = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionNotAuthenticated");
|
||||||
TwitchButtonState = AuthenticationButton.SignIn;
|
TwitchButtonState = AuthenticationButton.SignIn;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -130,13 +135,13 @@ namespace VDownload.GUI.ViewModels
|
|||||||
TwitchValidationResult validationResult = await _twitchAuthenticationService.ValidateToken(token);
|
TwitchValidationResult validationResult = await _twitchAuthenticationService.ValidateToken(token);
|
||||||
if (validationResult.Success)
|
if (validationResult.Success)
|
||||||
{
|
{
|
||||||
TwitchDescription = $"Signed in as {validationResult.TokenData.Login}. Expiration date: {validationResult.TokenData.ExpirationDate:dd.MM.yyyy HH:mm}";
|
TwitchDescription = string.Format(_stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionAuthenticated"), validationResult.TokenData.Login, validationResult.TokenData.ExpirationDate);
|
||||||
TwitchButtonState = AuthenticationButton.SignOut;
|
TwitchButtonState = AuthenticationButton.SignOut;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _twitchAuthenticationService.DeleteToken();
|
await _twitchAuthenticationService.DeleteToken();
|
||||||
TwitchDescription = "Token expired or is invalid. Please log in again";
|
TwitchDescription = _stringResourcesService.AuthenticationViewResources.Get("TwitchAuthenticationDescriptionAuthenticationInvalid");
|
||||||
TwitchButtonState = AuthenticationButton.SignIn;
|
TwitchButtonState = AuthenticationButton.SignIn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
110
VDownload.Core/VDownload.Core.ViewModels/BaseViewModel.cs
Normal file
110
VDownload.Core/VDownload.Core.ViewModels/BaseViewModel.cs
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Core.ViewModels.Authentication;
|
||||||
|
using VDownload.Core.ViewModels.Home;
|
||||||
|
using VDownload.Core.ViewModels.Settings;
|
||||||
|
using VDownload.Services.UI.DictionaryResources;
|
||||||
|
using VDownload.Services.UI.StringResources;
|
||||||
|
using VDownload.Toolkit.UI.Models;
|
||||||
|
|
||||||
|
namespace VDownload.Core.ViewModels
|
||||||
|
{
|
||||||
|
public partial class BaseViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
protected readonly IStringResourcesService _stringResourcesService;
|
||||||
|
protected readonly IDictionaryResourcesService _dictionaryResourcesService;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region FIELDS
|
||||||
|
|
||||||
|
protected readonly Type _settingsViewModel = typeof(SettingsViewModel);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private Type _currentViewModel;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private NavigationViewItem _selectedItem;
|
||||||
|
|
||||||
|
public ReadOnlyObservableCollection<NavigationViewItem> Items { get; protected set; }
|
||||||
|
public ReadOnlyObservableCollection<NavigationViewItem> FooterItems { get; protected set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public BaseViewModel(IStringResourcesService stringResourcesService, IDictionaryResourcesService dictionaryResourcesService)
|
||||||
|
{
|
||||||
|
_stringResourcesService = stringResourcesService;
|
||||||
|
_dictionaryResourcesService = dictionaryResourcesService;
|
||||||
|
|
||||||
|
Items = new ReadOnlyObservableCollection<NavigationViewItem>
|
||||||
|
(
|
||||||
|
new ObservableCollection<NavigationViewItem>
|
||||||
|
{
|
||||||
|
new NavigationViewItem()
|
||||||
|
{
|
||||||
|
Name = _stringResourcesService.BaseViewResources.Get("HomeNavigationViewItem"),
|
||||||
|
IconSource = _dictionaryResourcesService.Get<string>("ImageBaseViewHome"),
|
||||||
|
ViewModel = typeof(HomeViewModel),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
FooterItems = new ReadOnlyObservableCollection<NavigationViewItem>
|
||||||
|
(
|
||||||
|
new ObservableCollection<NavigationViewItem>
|
||||||
|
{
|
||||||
|
new NavigationViewItem()
|
||||||
|
{
|
||||||
|
Name = _stringResourcesService.BaseViewResources.Get("AuthenticationNavigationViewItem"),
|
||||||
|
IconSource = _dictionaryResourcesService.Get<string>("ImageBaseViewAuthentication"),
|
||||||
|
ViewModel = typeof(AuthenticationViewModel),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
SelectedItem = Items.First();
|
||||||
|
CurrentViewModel = SelectedItem.ViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public void Navigate(Microsoft.UI.Xaml.Controls.NavigationViewItemInvokedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.IsSettingsInvoked)
|
||||||
|
{
|
||||||
|
CurrentViewModel = _settingsViewModel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NavigationViewItem item = e.InvokedItemContainer.DataContext as NavigationViewItem;
|
||||||
|
CurrentViewModel = item.ViewModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,90 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Core.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Core.ViewModels.Home
|
||||||
|
{
|
||||||
|
public partial class HomeDownloadsViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
protected readonly IDownloadTaskManager _tasksManager;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public ReadOnlyObservableCollection<DownloadTask> Tasks => _tasksManager.Tasks;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private bool _taskListIsEmpty;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public HomeDownloadsViewModel(IDownloadTaskManager tasksManager)
|
||||||
|
{
|
||||||
|
_tasksManager = tasksManager;
|
||||||
|
_tasksManager.TaskCollectionChanged += Tasks_CollectionChanged;
|
||||||
|
|
||||||
|
_taskListIsEmpty = _tasksManager.Tasks.Count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public async Task StartCancelTask(DownloadTask task)
|
||||||
|
{
|
||||||
|
DownloadTaskStatus[] idleStatuses =
|
||||||
|
[
|
||||||
|
DownloadTaskStatus.Idle,
|
||||||
|
DownloadTaskStatus.EndedUnsuccessfully,
|
||||||
|
DownloadTaskStatus.EndedSuccessfully,
|
||||||
|
DownloadTaskStatus.EndedCancelled
|
||||||
|
];
|
||||||
|
if (idleStatuses.Contains(task.Status))
|
||||||
|
{
|
||||||
|
task.Enqueue();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await task.Cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public async Task RemoveTask(DownloadTask task)
|
||||||
|
{
|
||||||
|
await task.Cancel();
|
||||||
|
_tasksManager.RemoveTask(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
private void Tasks_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
TaskListIsEmpty = Tasks.Count == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,185 @@
|
|||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Core.Tasks;
|
||||||
|
using VDownload.Models;
|
||||||
|
using VDownload.Services.Data.Settings;
|
||||||
|
using VDownload.Services.UI.StoragePicker;
|
||||||
|
|
||||||
|
namespace VDownload.Core.ViewModels.Home
|
||||||
|
{
|
||||||
|
public partial class HomeVideoViewModel : ObservableObject
|
||||||
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
protected readonly IDownloadTaskManager _tasksManager;
|
||||||
|
|
||||||
|
protected readonly ISettingsService _settingsService;
|
||||||
|
protected readonly IStoragePickerService _storagePickerService;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region FIELDS
|
||||||
|
|
||||||
|
protected Video _video;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected Uri _thumbnailUrl;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected string _title;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected string _author;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected DateTime _publishDate;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected TimeSpan _duration;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected long _views;
|
||||||
|
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected ObservableCollection<VideoStream> _streams;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected VideoStream _selectedStream;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected MediaType _mediaType;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected TimeSpan _trimStart;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected TimeSpan _trimEnd;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected string _directoryPath;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected string _filename;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected VideoExtension _videoExtension;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
protected AudioExtension _audioExtension;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region EVENTS
|
||||||
|
|
||||||
|
public event EventHandler TaskAdded;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public HomeVideoViewModel(IDownloadTaskManager tasksManager, ISettingsService settingsService, IStoragePickerService storagePickerService)
|
||||||
|
{
|
||||||
|
_tasksManager = tasksManager;
|
||||||
|
_settingsService = settingsService;
|
||||||
|
_storagePickerService = storagePickerService;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public async void LoadVideo(Video video)
|
||||||
|
{
|
||||||
|
await _settingsService.Load();
|
||||||
|
|
||||||
|
_video = video;
|
||||||
|
|
||||||
|
ThumbnailUrl = video.ThumbnailUrl;
|
||||||
|
Title = video.Title;
|
||||||
|
Author = video.Author;
|
||||||
|
PublishDate = video.PublishDate;
|
||||||
|
Duration = video.Duration;
|
||||||
|
Views = video.Views;
|
||||||
|
|
||||||
|
Streams = [.. video.Streams];
|
||||||
|
SelectedStream = Streams[0];
|
||||||
|
MediaType = _settingsService.Data.Common.DefaultTaskSettings.MediaType;
|
||||||
|
TrimStart = TimeSpan.Zero;
|
||||||
|
TrimEnd = Duration;
|
||||||
|
DirectoryPath = _settingsService.Data.Common.DefaultTaskSettings.OutputDirectory;
|
||||||
|
Filename = Title.Length > 50 ? Title.Substring(0, 50) : Title;
|
||||||
|
VideoExtension = _settingsService.Data.Common.DefaultTaskSettings.VideoExtension;
|
||||||
|
AudioExtension = _settingsService.Data.Common.DefaultTaskSettings.AudioExtension;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public async Task Browse()
|
||||||
|
{
|
||||||
|
string? newDirectory = await _storagePickerService.OpenDirectory();
|
||||||
|
if (newDirectory is not null)
|
||||||
|
{
|
||||||
|
this.DirectoryPath = newDirectory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public void CreateTask()
|
||||||
|
{
|
||||||
|
_tasksManager.AddTask(_video, BuildDownloadOptions());
|
||||||
|
TaskAdded?.Invoke(this, EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
public void CreateTaskAndDownload()
|
||||||
|
{
|
||||||
|
DownloadTask task = _tasksManager.AddTask(_video, BuildDownloadOptions());
|
||||||
|
TaskAdded?.Invoke(this, EventArgs.Empty);
|
||||||
|
task.Enqueue();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
protected VideoDownloadOptions BuildDownloadOptions()
|
||||||
|
{
|
||||||
|
return new VideoDownloadOptions(Duration)
|
||||||
|
{
|
||||||
|
MediaType = this.MediaType,
|
||||||
|
SelectedStream = this.SelectedStream,
|
||||||
|
TrimStart = this.TrimStart,
|
||||||
|
TrimEnd = this.TrimEnd,
|
||||||
|
Directory = this.DirectoryPath,
|
||||||
|
Filename = string.Join("_", this.Filename.Split(Path.GetInvalidFileNameChars())),
|
||||||
|
Extension = (this.MediaType == MediaType.OnlyAudio ? this.AudioExtension.ToString() : this.VideoExtension.ToString()).ToLower(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,19 +2,17 @@
|
|||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using VDownload.Common;
|
using VDownload.Models;
|
||||||
using VDownload.Common.Exceptions;
|
using VDownload.Services.Data.Configuration;
|
||||||
using VDownload.Common.Models;
|
using VDownload.Services.Data.Settings;
|
||||||
using VDownload.GUI.Services.StoragePicker;
|
using VDownload.Services.UI.StringResources;
|
||||||
using VDownload.Services.Search;
|
using VDownload.Sources;
|
||||||
using VDownload.Tasks;
|
using VDownload.Sources.Common;
|
||||||
|
|
||||||
namespace VDownload.GUI.ViewModels
|
namespace VDownload.Core.ViewModels.Home
|
||||||
{
|
{
|
||||||
public partial class HomeViewModel : ObservableObject
|
public partial class HomeViewModel : ObservableObject
|
||||||
{
|
{
|
||||||
@@ -39,9 +37,21 @@ namespace VDownload.GUI.ViewModels
|
|||||||
|
|
||||||
#region SERVICES
|
#region SERVICES
|
||||||
|
|
||||||
private IStoragePickerService _storagePickerService;
|
protected readonly IConfigurationService _configurationService;
|
||||||
private ISearchService _searchService;
|
protected readonly ISettingsService _settingsService;
|
||||||
private IDownloadTasksManager _tasksService;
|
protected readonly IStringResourcesService _stringResourcesService;
|
||||||
|
protected readonly ISearchService _searchService;
|
||||||
|
|
||||||
|
protected readonly HomeVideoViewModel _videoViewModel;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region FIELDS
|
||||||
|
|
||||||
|
protected readonly Type _downloadsView = typeof(HomeDownloadsViewModel);
|
||||||
|
protected readonly Type _videoView = typeof(HomeVideoViewModel);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -49,27 +59,10 @@ namespace VDownload.GUI.ViewModels
|
|||||||
|
|
||||||
#region PROPERTIES
|
#region PROPERTIES
|
||||||
|
|
||||||
// MAIN
|
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private MainContentType _mainContent;
|
private Type _mainContent;
|
||||||
|
|
||||||
|
|
||||||
// DOWNLOADS
|
|
||||||
public ObservableCollection<DownloadTask> Tasks => _tasksService.Tasks;
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private bool _taskListIsEmpty;
|
|
||||||
|
|
||||||
|
|
||||||
// VIDEO
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private DownloadTask _task;
|
|
||||||
|
|
||||||
|
|
||||||
// OPTION BAR
|
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private OptionBarContentType _optionBarContent;
|
private OptionBarContentType _optionBarContent;
|
||||||
|
|
||||||
@@ -103,14 +96,15 @@ namespace VDownload.GUI.ViewModels
|
|||||||
|
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public HomeViewModel(IStoragePickerService storagePickerService, ISearchService searchService, IDownloadTasksManager tasksService)
|
public HomeViewModel(IConfigurationService configurationService, ISettingsService settingsService, IStringResourcesService stringResourcesService, ISearchService searchService, HomeVideoViewModel videoViewModel)
|
||||||
{
|
{
|
||||||
_storagePickerService = storagePickerService;
|
_configurationService = configurationService;
|
||||||
|
_settingsService = settingsService;
|
||||||
|
_stringResourcesService = stringResourcesService;
|
||||||
_searchService = searchService;
|
_searchService = searchService;
|
||||||
_tasksService = tasksService;
|
|
||||||
_tasksService.Tasks.CollectionChanged += Tasks_CollectionChanged;
|
|
||||||
|
|
||||||
_taskListIsEmpty = _tasksService.Tasks.Count == 0;
|
_videoViewModel = videoViewModel;
|
||||||
|
_videoViewModel.TaskAdded += VideoViewModel_TaskAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
@@ -120,9 +114,11 @@ namespace VDownload.GUI.ViewModels
|
|||||||
#region COMMANDS
|
#region COMMANDS
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public void Navigation()
|
public async Task Navigation()
|
||||||
{
|
{
|
||||||
MainContent = MainContentType.Downloads;
|
await _settingsService.Load();
|
||||||
|
|
||||||
|
MainContent = _downloadsView;
|
||||||
|
|
||||||
OptionBarContent = OptionBarContentType.None;
|
OptionBarContent = OptionBarContentType.None;
|
||||||
OptionBarMessage = null;
|
OptionBarMessage = null;
|
||||||
@@ -130,74 +126,14 @@ namespace VDownload.GUI.ViewModels
|
|||||||
OptionBarPlaylistSearchButtonChecked = false;
|
OptionBarPlaylistSearchButtonChecked = false;
|
||||||
OptionBarSearchNotPending = true;
|
OptionBarSearchNotPending = true;
|
||||||
OptionBarVideoSearchTBValue = string.Empty;
|
OptionBarVideoSearchTBValue = string.Empty;
|
||||||
OptionBarPlaylistSearchNBValue = 1; // TODO: load from settings
|
OptionBarPlaylistSearchNBValue = _settingsService.Data.Common.MaxNumberOfVideosToGetFromPlaylist;
|
||||||
OptionBarPlaylistSearchTBValue = string.Empty;
|
OptionBarPlaylistSearchTBValue = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// DOWNLOADS
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
public void StartCancelTask(DownloadTask task)
|
|
||||||
{
|
|
||||||
DownloadTaskStatus[] idleStatuses =
|
|
||||||
[
|
|
||||||
DownloadTaskStatus.Idle,
|
|
||||||
DownloadTaskStatus.EndedUnsuccessfully,
|
|
||||||
DownloadTaskStatus.EndedSuccessfully,
|
|
||||||
DownloadTaskStatus.EndedCancelled
|
|
||||||
];
|
|
||||||
if (idleStatuses.Contains(task.Status))
|
|
||||||
{
|
|
||||||
task.Enqueue();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
task.Cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// VIDEO
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
public async Task Browse()
|
|
||||||
{
|
|
||||||
string? newDirectory = await _storagePickerService.OpenDirectory();
|
|
||||||
if (newDirectory is not null)
|
|
||||||
{
|
|
||||||
Task.DirectoryPath = newDirectory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RelayCommand]
|
|
||||||
public async Task CreateTask()
|
|
||||||
{
|
|
||||||
string extension = Task.MediaType switch
|
|
||||||
{
|
|
||||||
MediaType.OnlyAudio => Task.AudioExtension.ToString(),
|
|
||||||
_ => Task.VideoExtension.ToString()
|
|
||||||
};
|
|
||||||
|
|
||||||
Task.Filename = string.Join("_", Task.Filename.Split(Path.GetInvalidFileNameChars()));
|
|
||||||
string file = $"{Task.Filename}.{extension}";
|
|
||||||
string path = Path.Combine(Task.DirectoryPath, file);
|
|
||||||
|
|
||||||
await File.WriteAllBytesAsync(path, [0x00]);
|
|
||||||
File.Delete(path);
|
|
||||||
|
|
||||||
_tasksService.AddTask(Task);
|
|
||||||
|
|
||||||
Navigation();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// OPTION BAR
|
|
||||||
|
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public void LoadFromSubscription()
|
public void LoadFromSubscription()
|
||||||
{
|
{
|
||||||
MainContent = MainContentType.Downloads;
|
MainContent = _downloadsView;
|
||||||
|
|
||||||
OptionBarContent = OptionBarContentType.None;
|
OptionBarContent = OptionBarContentType.None;
|
||||||
OptionBarVideoSearchButtonChecked = false;
|
OptionBarVideoSearchButtonChecked = false;
|
||||||
@@ -210,7 +146,7 @@ namespace VDownload.GUI.ViewModels
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public void VideoSearchShow()
|
public void VideoSearchShow()
|
||||||
{
|
{
|
||||||
MainContent = MainContentType.Downloads;
|
MainContent = _downloadsView;
|
||||||
|
|
||||||
if (OptionBarContent != OptionBarContentType.VideoSearch)
|
if (OptionBarContent != OptionBarContentType.VideoSearch)
|
||||||
{
|
{
|
||||||
@@ -226,7 +162,7 @@ namespace VDownload.GUI.ViewModels
|
|||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
public void PlaylistSearchShow()
|
public void PlaylistSearchShow()
|
||||||
{
|
{
|
||||||
MainContent = MainContentType.Downloads;
|
MainContent = _downloadsView;
|
||||||
|
|
||||||
if (OptionBarContent != OptionBarContentType.PlaylistSearch)
|
if (OptionBarContent != OptionBarContentType.PlaylistSearch)
|
||||||
{
|
{
|
||||||
@@ -244,7 +180,7 @@ namespace VDownload.GUI.ViewModels
|
|||||||
{
|
{
|
||||||
OptionBarSearchNotPending = false;
|
OptionBarSearchNotPending = false;
|
||||||
OptionBarLoading = true;
|
OptionBarLoading = true;
|
||||||
OptionBarMessage = "Loading...";
|
OptionBarMessage = _stringResourcesService.HomeViewResources.Get("OptionBarMessageLoading");
|
||||||
|
|
||||||
Video video;
|
Video video;
|
||||||
try
|
try
|
||||||
@@ -259,9 +195,9 @@ namespace VDownload.GUI.ViewModels
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Task = new DownloadTask(video);
|
_videoViewModel.LoadVideo(video);
|
||||||
|
|
||||||
MainContent = MainContentType.Video;
|
MainContent = _videoView;
|
||||||
|
|
||||||
OptionBarSearchNotPending = true;
|
OptionBarSearchNotPending = true;
|
||||||
OptionBarLoading = false;
|
OptionBarLoading = false;
|
||||||
@@ -273,7 +209,7 @@ namespace VDownload.GUI.ViewModels
|
|||||||
{
|
{
|
||||||
OptionBarSearchNotPending = false;
|
OptionBarSearchNotPending = false;
|
||||||
OptionBarLoading = true;
|
OptionBarLoading = true;
|
||||||
OptionBarMessage = "Loading...";
|
OptionBarMessage = _stringResourcesService.HomeViewResources.Get("OptionBarMessageLoading");
|
||||||
|
|
||||||
Playlist playlist;
|
Playlist playlist;
|
||||||
try
|
try
|
||||||
@@ -303,12 +239,9 @@ namespace VDownload.GUI.ViewModels
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region EVENT HANDLERS
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
private void Tasks_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
|
private async void VideoViewModel_TaskAdded(object sender, EventArgs e) => await Navigation();
|
||||||
{
|
|
||||||
TaskListIsEmpty = Tasks.Count == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@@ -4,16 +4,9 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.GUI.ViewModels
|
namespace VDownload.Core.ViewModels.Settings
|
||||||
{
|
{
|
||||||
public class SettingsViewModel
|
public class SettingsViewModel
|
||||||
{
|
{
|
||||||
#region CONSTRUCTORS
|
|
||||||
|
|
||||||
public SettingsViewModel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||||
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||||
|
<RootNamespace>VDownload.Core.ViewModels</RootNamespace>
|
||||||
|
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||||
|
<UseWinUI>true</UseWinUI>
|
||||||
|
<UseRidGraph>true</UseRidGraph>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||||
|
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||||
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.Data\VDownload.Services.Data.Settings\VDownload.Services.Data.Settings.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.UI\VDownload.Services.UI.Dialogs\VDownload.Services.UI.Dialogs.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.UI\VDownload.Services.UI.DictionaryResources\VDownload.Services.UI.DictionaryResources.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.UI\VDownload.Services.UI.StoragePicker\VDownload.Services.UI.StoragePicker.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.UI\VDownload.Services.UI.StringResources\VDownload.Services.UI.StringResources.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.UI\VDownload.Services.UI.WebView\VDownload.Services.UI.WebView.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Sources\VDownload.Sources.Twitch\VDownload.Sources.Twitch.Authentication\VDownload.Sources.Twitch.Authentication.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Sources\VDownload.Sources\VDownload.Sources.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Models\VDownload.Toolkit.UI.Models.csproj" />
|
||||||
|
<ProjectReference Include="..\VDownload.Core.Tasks\VDownload.Core.Tasks.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Page
|
<Page
|
||||||
x:Class="VDownload.GUI.Views.AuthenticationView"
|
x:Class="VDownload.Core.Views.Authentication.AuthenticationView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="using:VDownload.GUI.Views"
|
xmlns:local="using:VDownload.Core.Views.Authentication"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:ctuc="using:CommunityToolkit.WinUI.UI.Controls"
|
xmlns:ctuc="using:CommunityToolkit.WinUI.UI.Controls"
|
||||||
@@ -18,50 +18,51 @@
|
|||||||
<ic:InvokeCommandAction Command="{Binding NavigationCommand}"/>
|
<ic:InvokeCommandAction Command="{Binding NavigationCommand}"/>
|
||||||
</ic:EventTriggerBehavior>
|
</ic:EventTriggerBehavior>
|
||||||
</i:Interaction.Behaviors>
|
</i:Interaction.Behaviors>
|
||||||
<Grid Padding="20" RowSpacing="20">
|
<Grid Padding="20"
|
||||||
|
RowSpacing="20">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<TextBlock Grid.Row="0"
|
<TextBlock x:Uid="/VDownload.Core.Strings/AuthenticationViewResources/Header"
|
||||||
|
Grid.Row="0"
|
||||||
FontSize="28"
|
FontSize="28"
|
||||||
FontWeight="SemiBold"
|
FontWeight="SemiBold"/>
|
||||||
Text="Authentication"/>
|
|
||||||
<StackPanel Grid.Row="1"
|
<StackPanel Grid.Row="1"
|
||||||
Spacing="10">
|
Spacing="10">
|
||||||
<ctc:SettingsCard Header="Twitch">
|
<ctc:SettingsCard Header="Twitch">
|
||||||
<i:Interaction.Behaviors>
|
<i:Interaction.Behaviors>
|
||||||
<ic:DataTriggerBehavior Binding="{Binding TwitchButtonState, Converter={StaticResource EnumToStringConverter}}"
|
<ic:DataTriggerBehavior Binding="{Binding TwitchButtonState, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
ComparisonCondition="NotEqual"
|
ComparisonCondition="NotEqual"
|
||||||
Value="Loading">
|
Value="Loading">
|
||||||
<ic:ChangePropertyAction PropertyName="Description"
|
<ic:ChangePropertyAction PropertyName="Description"
|
||||||
Value="{Binding TwitchDescription}"/>
|
Value="{Binding TwitchDescription}"/>
|
||||||
<ic:ChangePropertyAction PropertyName="Content">
|
<ic:ChangePropertyAction PropertyName="Content">
|
||||||
<ic:ChangePropertyAction.Value>
|
<ic:ChangePropertyAction.Value>
|
||||||
<Button Command="{Binding TwitchAuthenticationCommand}">
|
<Button Command="{Binding TwitchAuthenticationCommand}">
|
||||||
<i:Interaction.Behaviors>
|
<i:Interaction.Behaviors>
|
||||||
<ic:DataTriggerBehavior Binding="{Binding TwitchButtonState, Converter={StaticResource EnumToStringConverter}}"
|
<ic:DataTriggerBehavior Binding="{Binding TwitchButtonState, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
ComparisonCondition="Equal"
|
ComparisonCondition="Equal"
|
||||||
Value="SignIn">
|
Value="SignIn">
|
||||||
<ic:ChangePropertyAction PropertyName="Content"
|
<ic:ChangePropertyAction x:Uid="/VDownload.Core.Strings/AuthenticationViewResources/AuthenticationButtonSignIn"
|
||||||
Value="Sign in"/>
|
PropertyName="Content"/>
|
||||||
</ic:DataTriggerBehavior>
|
</ic:DataTriggerBehavior>
|
||||||
<ic:DataTriggerBehavior Binding="{Binding TwitchButtonState, Converter={StaticResource EnumToStringConverter}}"
|
<ic:DataTriggerBehavior Binding="{Binding TwitchButtonState, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
ComparisonCondition="Equal"
|
ComparisonCondition="Equal"
|
||||||
Value="SignOut">
|
Value="SignOut">
|
||||||
<ic:ChangePropertyAction PropertyName="Content"
|
<ic:ChangePropertyAction x:Uid="/VDownload.Core.Strings/AuthenticationViewResources/AuthenticationButtonSignOut"
|
||||||
Value="Sign out"/>
|
PropertyName="Content"/>
|
||||||
</ic:DataTriggerBehavior>
|
</ic:DataTriggerBehavior>
|
||||||
</i:Interaction.Behaviors>
|
</i:Interaction.Behaviors>
|
||||||
</Button>
|
</Button>
|
||||||
</ic:ChangePropertyAction.Value>
|
</ic:ChangePropertyAction.Value>
|
||||||
</ic:ChangePropertyAction>
|
</ic:ChangePropertyAction>
|
||||||
</ic:DataTriggerBehavior>
|
</ic:DataTriggerBehavior>
|
||||||
<ic:DataTriggerBehavior Binding="{Binding TwitchButtonState, Converter={StaticResource EnumToStringConverter}}"
|
<ic:DataTriggerBehavior Binding="{Binding TwitchButtonState, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
ComparisonCondition="Equal"
|
ComparisonCondition="Equal"
|
||||||
Value="Loading">
|
Value="Loading">
|
||||||
<ic:ChangePropertyAction PropertyName="Description"
|
<ic:ChangePropertyAction x:Uid="/VDownload.Core.Strings/AuthenticationViewResources/AuthenticationDescriptionLoading"
|
||||||
Value="Loading..."/>
|
PropertyName="Description"/>
|
||||||
<ic:ChangePropertyAction PropertyName="Content">
|
<ic:ChangePropertyAction PropertyName="Content">
|
||||||
<ic:ChangePropertyAction.Value>
|
<ic:ChangePropertyAction.Value>
|
||||||
<ProgressRing Width="20"
|
<ProgressRing Width="20"
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using VDownload.Core.ViewModels.Authentication;
|
||||||
|
|
||||||
|
namespace VDownload.Core.Views.Authentication
|
||||||
|
{
|
||||||
|
public sealed partial class AuthenticationView : Page
|
||||||
|
{
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public AuthenticationView(AuthenticationViewModel viewModel)
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
this.DataContext = viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,53 +1,49 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Window
|
<Window
|
||||||
x:Class="VDownload.MainWindow"
|
x:Class="VDownload.Core.Views.BaseWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="using:VDownload"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:i="using:Microsoft.Xaml.Interactivity"
|
xmlns:i="using:Microsoft.Xaml.Interactivity"
|
||||||
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
|
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
|
||||||
xmlns:cb="using:VDownload.GUI.Customs.Behaviors"
|
xmlns:cb="using:VDownload.Toolkit.UI.Behaviors"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<Window.SystemBackdrop>
|
<Window.SystemBackdrop>
|
||||||
<MicaBackdrop Kind="Base"/>
|
<MicaBackdrop Kind="Base"/>
|
||||||
</Window.SystemBackdrop>
|
</Window.SystemBackdrop>
|
||||||
<Grid x:Name="RootPanel" Loaded="RootPanel_Loaded">
|
<Grid x:Name="Root"
|
||||||
|
Loaded="Root_Loaded">
|
||||||
<Border x:Name="AppTitleBar"
|
<Border x:Name="AppTitleBar"
|
||||||
IsHitTestVisible="True"
|
IsHitTestVisible="True"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
Background="Transparent"
|
|
||||||
Height="40"
|
Height="40"
|
||||||
Canvas.ZIndex="1"
|
Canvas.ZIndex="1"
|
||||||
Margin="55,4,0,0">
|
Margin="55,4,0,0">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<Image x:Name="TitleBarIcon"
|
<Image HorizontalAlignment="Left"
|
||||||
HorizontalAlignment="Left"
|
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Source="{StaticResource ImageLogo}"
|
Source="{StaticResource ImageLogo}"
|
||||||
Width="16"
|
Width="16"
|
||||||
Height="16"/>
|
Height="16"/>
|
||||||
<TextBlock x:Name="TitleBarTextBlock"
|
<TextBlock Text="VDownload"
|
||||||
Text="VDownload"
|
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Margin="12, 0, 0, 0"
|
Margin="12, 0, 0, 0"
|
||||||
Style="{StaticResource CaptionTextBlockStyle}" />
|
Style="{StaticResource CaptionTextBlockStyle}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
<NavigationView x:Name="NavigationView"
|
<NavigationView IsTitleBarAutoPaddingEnabled="True"
|
||||||
IsTitleBarAutoPaddingEnabled="True"
|
|
||||||
IsBackButtonVisible="Collapsed"
|
IsBackButtonVisible="Collapsed"
|
||||||
PaneDisplayMode="LeftCompact"
|
PaneDisplayMode="LeftCompact"
|
||||||
Canvas.ZIndex="0"
|
Canvas.ZIndex="0"
|
||||||
Background="Transparent"
|
|
||||||
MenuItemsSource="{Binding Items}"
|
MenuItemsSource="{Binding Items}"
|
||||||
FooterMenuItemsSource="{Binding FooterItems}"
|
FooterMenuItemsSource="{Binding FooterItems}"
|
||||||
SelectedItem="{Binding SelectedItem}">
|
SelectedItem="{Binding SelectedItem}"
|
||||||
|
Background="Transparent">
|
||||||
<i:Interaction.Behaviors>
|
<i:Interaction.Behaviors>
|
||||||
<cb:EventToCommandBehavior Command="{Binding NavigateCommand}"
|
<cb:EventToCommandBehavior Command="{Binding NavigateCommand}"
|
||||||
Event="ItemInvoked"
|
Event="ItemInvoked"
|
||||||
PassArguments="True"/>
|
PassArguments="True"/>
|
||||||
</i:Interaction.Behaviors>
|
</i:Interaction.Behaviors>
|
||||||
<NavigationView.Resources>
|
<NavigationView.Resources>
|
||||||
<SolidColorBrush x:Key="NavigationViewContentBackground"
|
<SolidColorBrush x:Key="NavigationViewContentBackground"
|
||||||
@@ -65,11 +61,6 @@
|
|||||||
<Frame Margin="0,48,0,0"
|
<Frame Margin="0,48,0,0"
|
||||||
CornerRadius="10"
|
CornerRadius="10"
|
||||||
Content="{Binding CurrentViewModel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ViewModelToViewConverter}}">
|
Content="{Binding CurrentViewModel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ViewModelToViewConverter}}">
|
||||||
<Frame.ContentTransitions>
|
|
||||||
<TransitionCollection>
|
|
||||||
<ContentThemeTransition/>
|
|
||||||
</TransitionCollection>
|
|
||||||
</Frame.ContentTransitions>
|
|
||||||
</Frame>
|
</Frame>
|
||||||
</NavigationView>
|
</NavigationView>
|
||||||
</Grid>
|
</Grid>
|
||||||
59
VDownload.Core/VDownload.Core.Views/BaseWindow.xaml.cs
Normal file
59
VDownload.Core/VDownload.Core.Views/BaseWindow.xaml.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
using Microsoft.UI.Xaml.Input;
|
||||||
|
using Microsoft.UI.Xaml.Media;
|
||||||
|
using Microsoft.UI.Xaml.Navigation;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
|
using VDownload.Core.ViewModels;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Collections;
|
||||||
|
|
||||||
|
namespace VDownload.Core.Views
|
||||||
|
{
|
||||||
|
public sealed partial class BaseWindow : Window
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public XamlRoot XamlRoot => this.Root.XamlRoot;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region EVENTS
|
||||||
|
|
||||||
|
public event EventHandler RootLoaded;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public BaseWindow(BaseViewModel viewModel)
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
|
||||||
|
this.ExtendsContentIntoTitleBar = true;
|
||||||
|
this.SetTitleBar(this.AppTitleBar);
|
||||||
|
|
||||||
|
this.Root.DataContext = viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PRIVATE METHODS
|
||||||
|
|
||||||
|
private void Root_Loaded(object sender, RoutedEventArgs e) => RootLoaded?.Invoke(this, EventArgs.Empty);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
397
VDownload.Core/VDownload.Core.Views/Home/HomeDownloadsView.xaml
Normal file
397
VDownload.Core/VDownload.Core.Views/Home/HomeDownloadsView.xaml
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Page
|
||||||
|
x:Class="VDownload.Core.Views.Home.HomeDownloadsView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:VDownload.Core.Views.Home"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:i="using:Microsoft.Xaml.Interactivity"
|
||||||
|
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
|
||||||
|
xmlns:m="using:VDownload.Models"
|
||||||
|
xmlns:ct="using:CommunityToolkit.WinUI"
|
||||||
|
xmlns:ctc="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:ctuc="using:CommunityToolkit.WinUI.UI.Controls"
|
||||||
|
xmlns:ctb="using:CommunityToolkit.WinUI.Behaviors"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
x:Name="Root"
|
||||||
|
Background="Transparent">
|
||||||
|
<ctuc:SwitchPresenter Value="{Binding TaskListIsEmpty, Converter={StaticResource ObjectToStringConverter}}">
|
||||||
|
<ctuc:Case Value="True">
|
||||||
|
<StackPanel HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<Image Source="{StaticResource ImageHomeDownloadsViewNoTasks}"
|
||||||
|
Width="100"/>
|
||||||
|
<TextBlock Text="Click Video/Playlist search button to add new tasks"
|
||||||
|
Foreground="{StaticResource GreyText}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</ctuc:Case>
|
||||||
|
<ctuc:Case Value="False">
|
||||||
|
<ScrollViewer>
|
||||||
|
<ItemsControl ItemsSource="{Binding Tasks}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid Background="{ThemeResource ViewBackgroundColor}"
|
||||||
|
CornerRadius="10"
|
||||||
|
Height="150"
|
||||||
|
Margin="0,0,0,10">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Image Grid.Column="0"
|
||||||
|
Source="{Binding Video.ThumbnailUrl}"
|
||||||
|
VerticalAlignment="Stretch"/>
|
||||||
|
<Grid Grid.Column="1"
|
||||||
|
Margin="10"
|
||||||
|
RowSpacing="10">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid Grid.Row="0"
|
||||||
|
ColumnSpacing="10"
|
||||||
|
HorizontalAlignment="Left">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock Grid.Column="0"
|
||||||
|
FontWeight="SemiBold"
|
||||||
|
FontSize="18"
|
||||||
|
Text="{Binding Video.Title}"
|
||||||
|
TextTrimming="CharacterEllipsis"/>
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontWeight="Light"
|
||||||
|
FontSize="12"
|
||||||
|
Text="{Binding Video.Author}"/>
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Row="1"
|
||||||
|
RowSpacing="10"
|
||||||
|
ColumnSpacing="10">
|
||||||
|
<Grid.Resources>
|
||||||
|
<x:Double x:Key="TextSize">12</x:Double>
|
||||||
|
</Grid.Resources>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Image Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
Source="{ThemeResource ImageHomeDownloadsViewQuality}"/>
|
||||||
|
<StackPanel Grid.Row="0"
|
||||||
|
Grid.Column="1"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<ctuc:SwitchPresenter Value="{Binding DownloadOptions.MediaType, Converter={StaticResource ObjectToStringConverter}}">
|
||||||
|
<ctuc:Case Value="Original">
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/MediaTypeOriginal"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
</ctuc:Case>
|
||||||
|
<ctuc:Case Value="OnlyVideo">
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/MediaTypeOnlyVideo"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
</ctuc:Case>
|
||||||
|
<ctuc:Case Value="OnlyAudio">
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/MediaTypeOnlyAudio"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
</ctuc:Case>
|
||||||
|
</ctuc:SwitchPresenter>
|
||||||
|
<TextBlock FontSize="{StaticResource TextSize}">
|
||||||
|
<Run Text=" ("/><Run Text="{Binding DownloadOptions.SelectedStream.Name}"/>)
|
||||||
|
</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
<Image Grid.Row="1"
|
||||||
|
Grid.Column="0"
|
||||||
|
Source="{ThemeResource ImageHomeDownloadsViewTime}"/>
|
||||||
|
<StackPanel Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<TextBlock Text="{Binding DownloadOptions.DurationAfterTrim}"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
<TextBlock Visibility="{Binding DownloadOptions.IsTrimmed, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||||
|
FontSize="{StaticResource TextSize}">
|
||||||
|
<Run Text=" "/>(<Run Text="{Binding DownloadOptions.TrimStart}"/> - <Run Text="{Binding DownloadOptions.TrimEnd}"/>)
|
||||||
|
</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
<Image Grid.Row="2"
|
||||||
|
Grid.Column="0"
|
||||||
|
Source="{ThemeResource ImageHomeDownloadsViewFile}"/>
|
||||||
|
<TextBlock Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
FontSize="{StaticResource TextSize}"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<Run Text="{Binding DownloadOptions.Directory}"/>\<Run Text="{Binding DownloadOptions.Filename}"/>.<Run Text="{Binding DownloadOptions.Extension}"/>
|
||||||
|
</TextBlock>
|
||||||
|
<Image Grid.Row="3"
|
||||||
|
Grid.Column="0">
|
||||||
|
<i:Interaction.Behaviors>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Idle">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Source"
|
||||||
|
Value="{ThemeResource ImageHomeDownloadsViewIdle}"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Queued">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Source"
|
||||||
|
Value="{ThemeResource ImageHomeDownloadsViewQueued}"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Initializing">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Source"
|
||||||
|
Value="{ThemeResource ImageHomeDownloadsViewInitializing}"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Downloading">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Source"
|
||||||
|
Value="{ThemeResource ImageHomeDownloadsViewDownloading}"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Processing">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Source"
|
||||||
|
Value="{ThemeResource ImageHomeDownloadsViewProcessing}"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Finalizing">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Source"
|
||||||
|
Value="{ThemeResource ImageHomeDownloadsViewFinalizing}"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="EndedUnsuccessfully">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Source"
|
||||||
|
Value="{ThemeResource ImageHomeDownloadsViewError}"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="EndedSuccessfully">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Source"
|
||||||
|
Value="{ThemeResource ImageHomeDownloadsViewDone}"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="EndedCancelled">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Source"
|
||||||
|
Value="{ThemeResource ImageHomeDownloadsViewCancelled}"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
</i:Interaction.Behaviors>
|
||||||
|
</Image>
|
||||||
|
<Border Grid.Row="3"
|
||||||
|
Grid.Column="1"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<i:Interaction.Behaviors>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Idle">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Child">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/StatusIdle"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Queued">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Child">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/StatusQueued"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Initializing">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Child">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/StatusInitializing"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Downloading">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Child">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/StatusDownloading"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
<TextBlock Text="{Binding Progress, Converter={StaticResource StringFormatConverter}, ConverterParameter='{} ({0:0.##}%)'}"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Processing">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Child">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<TextBlock FontSize="{StaticResource TextSize}">
|
||||||
|
<Run x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/StatusProcessing"/><Run Text=" ("/><Run Text="{Binding Progress, Converter={StaticResource StringFormatConverter}, ConverterParameter='{}{0:0.##}'}"/>%)
|
||||||
|
</TextBlock>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Finalizing">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Child">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/StatusFinalizing"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="EndedUnsuccessfully">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Child">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<TextBlock FontSize="{StaticResource TextSize}">
|
||||||
|
<Run x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/StatusError"/><Run Text=" ("/><Run Text="{Binding Error}"/>)
|
||||||
|
</TextBlock>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="EndedSuccessfully">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Child">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/StatusDone"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="EndedCancelled">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Child">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeDownloadsViewResources/StatusCancelled"
|
||||||
|
FontSize="{StaticResource TextSize}"/>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
</i:Interaction.Behaviors>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Column="2"
|
||||||
|
Margin="0,0,5,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<AppBarButton Grid.Row="0"
|
||||||
|
Width="40"
|
||||||
|
Height="48">
|
||||||
|
<i:Interaction.Behaviors>
|
||||||
|
<ic:EventTriggerBehavior EventName="Click">
|
||||||
|
<ctb:NavigateToUriAction NavigateUri="{Binding Video.Url}"/>
|
||||||
|
</ic:EventTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Video.Source, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="Twitch">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Icon">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<BitmapIcon ShowAsMonochrome="False"
|
||||||
|
UriSource="{StaticResource ImageSourcesTwitch}"/>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
</i:Interaction.Behaviors>
|
||||||
|
</AppBarButton>
|
||||||
|
<AppBarButton Grid.Row="1"
|
||||||
|
Width="40"
|
||||||
|
Height="48"
|
||||||
|
Command="{Binding ElementName=Root, Path=DataContext.StartCancelTaskCommand}"
|
||||||
|
CommandParameter="{Binding}">
|
||||||
|
<i:Interaction.Behaviors>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToIntConverter}}"
|
||||||
|
ComparisonCondition="LessThan"
|
||||||
|
Value="4">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Icon">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<SymbolIcon Symbol="Download"/>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToIntConverter}}"
|
||||||
|
ComparisonCondition="GreaterThanOrEqual"
|
||||||
|
Value="4">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Icon">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<SymbolIcon Symbol="Cancel"/>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
</i:Interaction.Behaviors>
|
||||||
|
</AppBarButton>
|
||||||
|
<AppBarButton Grid.Row="2"
|
||||||
|
Icon="Delete"
|
||||||
|
Width="40"
|
||||||
|
Height="48"
|
||||||
|
Command="{Binding ElementName=Root, Path=DataContext.RemoveTaskCommand}"
|
||||||
|
CommandParameter="{Binding}"/>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<ProgressBar Grid.Row="1"
|
||||||
|
Value="{Binding Progress}"
|
||||||
|
Maximum="100">
|
||||||
|
<i:Interaction.Behaviors>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToIntConverter}}"
|
||||||
|
ComparisonCondition="LessThan"
|
||||||
|
Value="5">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Visibility" Value="Collapsed"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToIntConverter}}"
|
||||||
|
ComparisonCondition="GreaterThanOrEqual"
|
||||||
|
Value="5">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Visibility" Value="Visible"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToIntConverter}}"
|
||||||
|
ComparisonCondition="LessThan"
|
||||||
|
Value="7">
|
||||||
|
<ic:ChangePropertyAction PropertyName="IsIndeterminate" Value="True"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource ObjectToIntConverter}}"
|
||||||
|
ComparisonCondition="GreaterThanOrEqual"
|
||||||
|
Value="7">
|
||||||
|
<ic:ChangePropertyAction PropertyName="IsIndeterminate" Value="False"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
</i:Interaction.Behaviors>
|
||||||
|
</ProgressBar>
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</ScrollViewer>
|
||||||
|
</ctuc:Case>
|
||||||
|
</ctuc:SwitchPresenter>
|
||||||
|
|
||||||
|
</Page>
|
||||||
@@ -10,17 +10,17 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
using VDownload.GUI.ViewModels;
|
using VDownload.Core.ViewModels.Home;
|
||||||
using Windows.Foundation;
|
using Windows.Foundation;
|
||||||
using Windows.Foundation.Collections;
|
using Windows.Foundation.Collections;
|
||||||
|
|
||||||
namespace VDownload.GUI.Views
|
namespace VDownload.Core.Views.Home
|
||||||
{
|
{
|
||||||
public sealed partial class SettingsView : Page
|
public sealed partial class HomeDownloadsView : Page
|
||||||
{
|
{
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public SettingsView(SettingsViewModel viewModel)
|
public HomeDownloadsView(HomeDownloadsViewModel viewModel)
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
this.InitializeComponent();
|
||||||
this.DataContext = viewModel;
|
this.DataContext = viewModel;
|
||||||
226
VDownload.Core/VDownload.Core.Views/Home/HomeVideoView.xaml
Normal file
226
VDownload.Core/VDownload.Core.Views/Home/HomeVideoView.xaml
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Page
|
||||||
|
x:Class="VDownload.Core.Views.Home.HomeVideoView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:local="using:VDownload.Core.Views.Home"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:i="using:Microsoft.Xaml.Interactivity"
|
||||||
|
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
|
||||||
|
xmlns:m="using:VDownload.Models"
|
||||||
|
xmlns:ct="using:CommunityToolkit.WinUI"
|
||||||
|
xmlns:ctc="using:CommunityToolkit.WinUI.Controls"
|
||||||
|
xmlns:ctuc="using:CommunityToolkit.WinUI.UI.Controls"
|
||||||
|
xmlns:c="using:VDownload.Toolkit.UI.Controls"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Background="{ThemeResource ViewBackgroundColor}">
|
||||||
|
|
||||||
|
<Grid Padding="15"
|
||||||
|
RowSpacing="20">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="150"/>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid Grid.Row="0"
|
||||||
|
ColumnSpacing="10">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Border Grid.Column="0"
|
||||||
|
CornerRadius="{ThemeResource ControlCornerRadius}">
|
||||||
|
<Image Source="{Binding ThumbnailUrl}"
|
||||||
|
VerticalAlignment="Stretch"/>
|
||||||
|
</Border>
|
||||||
|
<StackPanel Grid.Column="1"
|
||||||
|
Spacing="15">
|
||||||
|
<TextBlock Text="{Binding Title}"
|
||||||
|
FontWeight="Bold"
|
||||||
|
FontSize="20"
|
||||||
|
TextWrapping="WrapWholeWords"/>
|
||||||
|
<Grid ColumnSpacing="10"
|
||||||
|
RowSpacing="10">
|
||||||
|
<Grid.Resources>
|
||||||
|
<x:Double x:Key="IconSize">18</x:Double>
|
||||||
|
</Grid.Resources>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Image Grid.Column="0"
|
||||||
|
Grid.Row="0"
|
||||||
|
Source="{ThemeResource ImageHomeVideoViewAuthor}"
|
||||||
|
Width="{StaticResource IconSize}"/>
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Grid.Row="0"
|
||||||
|
Text="{Binding Author}"/>
|
||||||
|
<Image Grid.Column="0"
|
||||||
|
Grid.Row="1"
|
||||||
|
Source="{ThemeResource ImageHomeVideoViewDate}"
|
||||||
|
Width="{StaticResource IconSize}"/>
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Grid.Row="1"
|
||||||
|
Text="{Binding PublishDate}"/>
|
||||||
|
<Image Grid.Column="0"
|
||||||
|
Grid.Row="2"
|
||||||
|
Source="{ThemeResource ImageHomeVideoViewTime}"
|
||||||
|
Width="{StaticResource IconSize}"/>
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Grid.Row="2"
|
||||||
|
Text="{Binding Duration}"/>
|
||||||
|
<Image Grid.Column="0"
|
||||||
|
Grid.Row="3"
|
||||||
|
Source="{ThemeResource ImageHomeVideoViewViews}"
|
||||||
|
Width="{StaticResource IconSize}"/>
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Grid.Row="3"
|
||||||
|
Text="{Binding Views}"/>
|
||||||
|
</Grid>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<ScrollViewer Grid.Row="1">
|
||||||
|
<StackPanel Spacing="20">
|
||||||
|
<StackPanel Spacing="5">
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/MediaOptionsHeader"
|
||||||
|
FontWeight="Bold"
|
||||||
|
FontSize="15"/>
|
||||||
|
<ctc:SettingsCard x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/QualitySettingsCard">
|
||||||
|
<ctc:SettingsCard.HeaderIcon>
|
||||||
|
<BitmapIcon ShowAsMonochrome="False"
|
||||||
|
UriSource="{ThemeResource ImageHomeVideoViewQuality}"/>
|
||||||
|
</ctc:SettingsCard.HeaderIcon>
|
||||||
|
<ComboBox ItemsSource="{Binding Streams}"
|
||||||
|
SelectedItem="{Binding SelectedStream, Mode=TwoWay}">
|
||||||
|
<!-- ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate -->
|
||||||
|
</ComboBox>
|
||||||
|
</ctc:SettingsCard>
|
||||||
|
<ctc:SettingsCard x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/MediaTypeSettingsCard">
|
||||||
|
<ctc:SettingsCard.HeaderIcon>
|
||||||
|
<BitmapIcon ShowAsMonochrome="False"
|
||||||
|
UriSource="{ThemeResource ImageHomeVideoViewMedia}"/>
|
||||||
|
</ctc:SettingsCard.HeaderIcon>
|
||||||
|
<ComboBox ItemsSource="{ct:EnumValues Type=m:MediaType}"
|
||||||
|
SelectedItem="{Binding MediaType, Mode=TwoWay}">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<ctuc:SwitchPresenter Value="{Binding Converter={StaticResource ObjectToStringConverter}}">
|
||||||
|
<ctuc:Case Value="Original">
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/MediaTypeOriginal"/>
|
||||||
|
</ctuc:Case>
|
||||||
|
<ctuc:Case Value="OnlyVideo">
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/MediaTypeOnlyVideo"/>
|
||||||
|
</ctuc:Case>
|
||||||
|
<ctuc:Case Value="OnlyAudio">
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/MediaTypeOnlyAudio"/>
|
||||||
|
</ctuc:Case>
|
||||||
|
</ctuc:SwitchPresenter>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</ctc:SettingsCard>
|
||||||
|
<ctc:SettingsExpander x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/TrimSettingsGroup">
|
||||||
|
<ctc:SettingsExpander.HeaderIcon>
|
||||||
|
<BitmapIcon ShowAsMonochrome="False"
|
||||||
|
UriSource="{ThemeResource ImageHomeVideoViewTrim}"/>
|
||||||
|
</ctc:SettingsExpander.HeaderIcon>
|
||||||
|
<ctc:SettingsExpander.Items>
|
||||||
|
<ctc:SettingsCard x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/TrimStartSettingsCard">
|
||||||
|
<c:TimeSpanControl Value="{Binding TrimStart, Mode=TwoWay}"
|
||||||
|
Maximum="{Binding TrimEnd, Mode=OneWay}"/>
|
||||||
|
</ctc:SettingsCard>
|
||||||
|
<ctc:SettingsCard x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/TrimEndSettingsCard">
|
||||||
|
<c:TimeSpanControl Minimum="{Binding TrimStart, Mode=OneWay}"
|
||||||
|
Value="{Binding TrimEnd, Mode=TwoWay}"
|
||||||
|
Maximum="{Binding Duration, Mode=OneWay}"/>
|
||||||
|
</ctc:SettingsCard>
|
||||||
|
</ctc:SettingsExpander.Items>
|
||||||
|
</ctc:SettingsExpander>
|
||||||
|
</StackPanel>
|
||||||
|
<StackPanel Spacing="5">
|
||||||
|
<TextBlock x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/FileOptionsHeader"
|
||||||
|
FontWeight="Bold"
|
||||||
|
FontSize="15"/>
|
||||||
|
<ctc:SettingsCard x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/DirectorySettingsCard"
|
||||||
|
Description="{Binding DirectoryPath}">
|
||||||
|
<ctc:SettingsCard.HeaderIcon>
|
||||||
|
<BitmapIcon ShowAsMonochrome="False"
|
||||||
|
UriSource="{ThemeResource ImageHomeVideoViewDirectory}"/>
|
||||||
|
</ctc:SettingsCard.HeaderIcon>
|
||||||
|
<Button x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/DirectorySettingsCardButton"
|
||||||
|
Command="{Binding BrowseCommand}"/>
|
||||||
|
</ctc:SettingsCard>
|
||||||
|
<ctc:SettingsCard x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/FilenameSettingsCard">
|
||||||
|
<ctc:SettingsCard.HeaderIcon>
|
||||||
|
<BitmapIcon ShowAsMonochrome="False"
|
||||||
|
UriSource="{ThemeResource ImageHomeVideoViewFilename}"/>
|
||||||
|
</ctc:SettingsCard.HeaderIcon>
|
||||||
|
<TextBox Text="{Binding Filename, Mode=TwoWay}"/>
|
||||||
|
</ctc:SettingsCard>
|
||||||
|
<ctc:SettingsCard x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/FileTypeSettingsCard">
|
||||||
|
<ctc:SettingsCard.HeaderIcon>
|
||||||
|
<BitmapIcon ShowAsMonochrome="False"
|
||||||
|
UriSource="{ThemeResource ImageHomeVideoViewExtension}"/>
|
||||||
|
</ctc:SettingsCard.HeaderIcon>
|
||||||
|
<i:Interaction.Behaviors>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding MediaType, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="OnlyAudio">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Content">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<ComboBox ItemsSource="{ct:EnumValues Type=m:AudioExtension}"
|
||||||
|
SelectedItem="{Binding AudioExtension, Mode=TwoWay}">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding MediaType, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="OnlyAudio">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Content">
|
||||||
|
<ic:ChangePropertyAction.Value>
|
||||||
|
<ComboBox ItemsSource="{ct:EnumValues Type=m:VideoExtension}"
|
||||||
|
SelectedItem="{Binding VideoExtension, Mode=TwoWay}">
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</ic:ChangePropertyAction.Value>
|
||||||
|
</ic:ChangePropertyAction>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
</i:Interaction.Behaviors>
|
||||||
|
</ctc:SettingsCard>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</ScrollViewer>
|
||||||
|
<StackPanel Grid.Row="2"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Spacing="10">
|
||||||
|
<Button x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/CreateAndStartButton"
|
||||||
|
Command="{Binding CreateTaskAndDownloadCommand}"/>
|
||||||
|
<Button x:Uid="/VDownload.Core.Strings/HomeVideoViewResources/CreateButton"
|
||||||
|
Style="{StaticResource AccentButtonStyle}"
|
||||||
|
Command="{Binding CreateTaskCommand}"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
@@ -10,17 +10,17 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
using System.Runtime.InteropServices.WindowsRuntime;
|
||||||
using VDownload.GUI.ViewModels;
|
using VDownload.Core.ViewModels.Home;
|
||||||
using Windows.Foundation;
|
using Windows.Foundation;
|
||||||
using Windows.Foundation.Collections;
|
using Windows.Foundation.Collections;
|
||||||
|
|
||||||
namespace VDownload.GUI.Views
|
namespace VDownload.Core.Views.Home
|
||||||
{
|
{
|
||||||
public sealed partial class HomeView : Page
|
public sealed partial class HomeVideoView : Page
|
||||||
{
|
{
|
||||||
#region CONSTRUCTORS
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
public HomeView(HomeViewModel viewModel)
|
public HomeVideoView(HomeVideoViewModel viewModel)
|
||||||
{
|
{
|
||||||
this.InitializeComponent();
|
this.InitializeComponent();
|
||||||
this.DataContext = viewModel;
|
this.DataContext = viewModel;
|
||||||
139
VDownload.Core/VDownload.Core.Views/Home/HomeView.xaml
Normal file
139
VDownload.Core/VDownload.Core.Views/Home/HomeView.xaml
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Page
|
||||||
|
x:Class="VDownload.Core.Views.Home.HomeView"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:i="using:Microsoft.Xaml.Interactivity"
|
||||||
|
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
|
||||||
|
xmlns:ctuc="using:CommunityToolkit.WinUI.UI.Controls"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Background="Transparent"
|
||||||
|
x:Name="Root">
|
||||||
|
<i:Interaction.Behaviors>
|
||||||
|
<ic:EventTriggerBehavior EventName="Loaded">
|
||||||
|
<ic:InvokeCommandAction Command="{Binding NavigationCommand}"/>
|
||||||
|
</ic:EventTriggerBehavior>
|
||||||
|
</i:Interaction.Behaviors>
|
||||||
|
<Grid RowSpacing="10"
|
||||||
|
Margin="10">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Frame Content="{Binding MainContent, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ViewModelToViewConverter}}">
|
||||||
|
|
||||||
|
</Frame>
|
||||||
|
<Grid Grid.Row="1"
|
||||||
|
Background="{ThemeResource OptionBarBackgroundColor}"
|
||||||
|
CornerRadius="10">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition Width="50"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<ctuc:UniformGrid Grid.Column="0"
|
||||||
|
Rows="1"
|
||||||
|
Margin="15,0,0,0">
|
||||||
|
<ctuc:UniformGrid.RowDefinitions>
|
||||||
|
<RowDefinition/>
|
||||||
|
</ctuc:UniformGrid.RowDefinitions>
|
||||||
|
<ctuc:UniformGrid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</ctuc:UniformGrid.ColumnDefinitions>
|
||||||
|
<ctuc:SwitchPresenter Grid.Row="0"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
Margin="0,0,15,0"
|
||||||
|
Value="{Binding OptionBarContent, Converter={StaticResource ObjectToStringConverter}}">
|
||||||
|
<i:Interaction.Behaviors>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding OptionBarContent, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="Equal"
|
||||||
|
Value="None">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Visibility"
|
||||||
|
Value="Collapsed"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
<ic:DataTriggerBehavior Binding="{Binding OptionBarContent, Converter={StaticResource ObjectToStringConverter}}"
|
||||||
|
ComparisonCondition="NotEqual"
|
||||||
|
Value="None">
|
||||||
|
<ic:ChangePropertyAction PropertyName="Visibility"
|
||||||
|
Value="Visible"/>
|
||||||
|
</ic:DataTriggerBehavior>
|
||||||
|
</i:Interaction.Behaviors>
|
||||||
|
<ctuc:Case Value="VideoSearch">
|
||||||
|
<Grid ColumnSpacing="10"
|
||||||
|
VerticalAlignment="Stretch">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBox x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarVideoSearchContentTextBox"
|
||||||
|
Grid.Column="0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{Binding OptionBarVideoSearchTBValue, Mode=TwoWay}"/>
|
||||||
|
<Button x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarSearchButton"
|
||||||
|
Grid.Column="1"
|
||||||
|
IsEnabled="{Binding OptionBarSearchNotPending}"
|
||||||
|
Command="{Binding VideoSearchStartCommand}"/>
|
||||||
|
</Grid>
|
||||||
|
</ctuc:Case>
|
||||||
|
<ctuc:Case Value="PlaylistSearch">
|
||||||
|
<Grid ColumnSpacing="10">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBox x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarPlaylistSearchContentTextBox"
|
||||||
|
Grid.Column="0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{Binding OptionBarPlaylistSearchTBValue, Mode=TwoWay}"/>
|
||||||
|
<NumberBox x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarPlaylistSearchContentNumberBox"
|
||||||
|
Grid.Column="1"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
SpinButtonPlacementMode="Compact"
|
||||||
|
SmallChange="1"
|
||||||
|
LargeChange="10"
|
||||||
|
Value="{Binding OptionBarPlaylistSearchNBValue, Mode=TwoWay}"
|
||||||
|
Minimum="0"/>
|
||||||
|
<Button x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarSearchButton"
|
||||||
|
Grid.Column="2"
|
||||||
|
IsEnabled="{Binding OptionBarSearchNotPending}"
|
||||||
|
Command="{Binding PlaylistSearchStartCommand}"/>
|
||||||
|
</Grid>
|
||||||
|
</ctuc:Case>
|
||||||
|
</ctuc:SwitchPresenter>
|
||||||
|
<StackPanel VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<ProgressRing Width="20"
|
||||||
|
Height="20"
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Visibility="{Binding OptionBarLoading, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||||
|
<TextBlock Text="{Binding OptionBarMessage}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</ctuc:UniformGrid>
|
||||||
|
<StackPanel Grid.Column="2"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<AppBarButton x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarLoadSubscription"
|
||||||
|
Icon="Favorite"
|
||||||
|
IsEnabled="{Binding OptionBarSearchNotPending}"
|
||||||
|
Command="{Binding LoadFromSubscriptionCommand}"/>
|
||||||
|
<AppBarToggleButton x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarVideoSearch"
|
||||||
|
Icon="Video"
|
||||||
|
IsEnabled="{Binding OptionBarSearchNotPending}"
|
||||||
|
IsChecked="{Binding OptionBarVideoSearchButtonChecked, Mode=TwoWay}"
|
||||||
|
Command="{Binding VideoSearchShowCommand}"/>
|
||||||
|
<AppBarToggleButton x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarPlaylistSearch"
|
||||||
|
Icon="List"
|
||||||
|
IsEnabled="{Binding OptionBarSearchNotPending}"
|
||||||
|
IsChecked="{Binding OptionBarPlaylistSearchButtonChecked, Mode=TwoWay}"
|
||||||
|
Command="{Binding PlaylistSearchShowCommand}"/>
|
||||||
|
<AppBarSeparator/>
|
||||||
|
<AppBarButton x:Uid="/VDownload.Core.Strings/HomeViewResources/OptionBarDownloadAll"
|
||||||
|
Icon="Download"
|
||||||
|
Command="{Binding DownloadCommand}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</Page>
|
||||||
18
VDownload.Core/VDownload.Core.Views/Home/HomeView.xaml.cs
Normal file
18
VDownload.Core/VDownload.Core.Views/Home/HomeView.xaml.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using VDownload.Core.ViewModels.Home;
|
||||||
|
|
||||||
|
namespace VDownload.Core.Views.Home
|
||||||
|
{
|
||||||
|
public sealed partial class HomeView : Page
|
||||||
|
{
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public HomeView(HomeViewModel viewModel)
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
this.DataContext = viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Page
|
<Page
|
||||||
x:Class="VDownload.GUI.Views.SettingsView"
|
x:Class="VDownload.Core.Views.Settings.SettingsView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="using:VDownload.GUI.Views"
|
xmlns:local="using:VDownload.Core.Views.Settings"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextBlock Text="Settings"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Microsoft.UI.Xaml.Controls;
|
||||||
|
using VDownload.Core.ViewModels.Settings;
|
||||||
|
|
||||||
|
namespace VDownload.Core.Views.Settings
|
||||||
|
{
|
||||||
|
public sealed partial class SettingsView : Page
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public new SettingsViewModel DataContext { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public SettingsView(SettingsViewModel viewModel)
|
||||||
|
{
|
||||||
|
this.InitializeComponent();
|
||||||
|
this.DataContext = viewModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||||
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||||
|
<RootNamespace>VDownload.Core.Views</RootNamespace>
|
||||||
|
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||||
|
<UseWinUI>true</UseWinUI>
|
||||||
|
<UseRidGraph>true</UseRidGraph>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="CommunityToolkit.WinUI" Version="7.1.2" />
|
||||||
|
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.0.240109" />
|
||||||
|
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.0.240109" />
|
||||||
|
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
|
||||||
|
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||||
|
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||||
|
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Behaviors\VDownload.Toolkit.UI.Behaviors.csproj" />
|
||||||
|
<ProjectReference Include="..\..\VDownload.Toolkit\VDownload.Toolkit.UI\VDownload.Toolkit.UI.Controls\VDownload.Toolkit.UI.Controls.csproj" />
|
||||||
|
<ProjectReference Include="..\VDownload.Core.Strings\VDownload.Core.Strings.csproj" />
|
||||||
|
<ProjectReference Include="..\VDownload.Core.ViewModels\VDownload.Core.ViewModels.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Authentication\AuthenticationView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</None>
|
||||||
|
<None Update="BaseWindow.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</None>
|
||||||
|
<None Update="Home\HomeDownloadsView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</None>
|
||||||
|
<None Update="Home\HomeVideoView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</None>
|
||||||
|
<None Update="Settings\SettingsView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Home\HomeVideoView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="BaseWindow.xaml">
|
||||||
|
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Home\HomeView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Home\HomeDownloadsView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Authentication\AuthenticationView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="Settings\SettingsView.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml.Data;
|
||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using VDownload.Core.ViewModels.Authentication;
|
||||||
using System.Threading.Tasks;
|
using VDownload.Core.ViewModels.Home;
|
||||||
using VDownload.GUI.ViewModels;
|
using VDownload.Core.ViewModels.Settings;
|
||||||
using VDownload.GUI.Views;
|
using VDownload.Core.Views.Authentication;
|
||||||
using VDownload.Services;
|
using VDownload.Core.Views.Home;
|
||||||
|
using VDownload.Core.Views.Settings;
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
namespace VDownload.Core.Views
|
||||||
{
|
{
|
||||||
public class ViewModelToViewConverter : IValueConverter
|
public class ViewModelToViewConverter : IValueConverter
|
||||||
{
|
{
|
||||||
@@ -18,21 +18,25 @@ namespace VDownload.GUI.Converters
|
|||||||
private readonly Dictionary<Type, Type> _viewModelViewBinding = new Dictionary<Type, Type>
|
private readonly Dictionary<Type, Type> _viewModelViewBinding = new Dictionary<Type, Type>
|
||||||
{
|
{
|
||||||
{ typeof(HomeViewModel), typeof(HomeView) },
|
{ typeof(HomeViewModel), typeof(HomeView) },
|
||||||
|
{ typeof(HomeDownloadsViewModel), typeof(HomeDownloadsView) },
|
||||||
|
{ typeof(HomeVideoViewModel), typeof(HomeVideoView) },
|
||||||
{ typeof(SettingsViewModel), typeof(SettingsView) },
|
{ typeof(SettingsViewModel), typeof(SettingsView) },
|
||||||
{ typeof(AuthenticationViewModel), typeof(AuthenticationView) }
|
{ typeof(AuthenticationViewModel), typeof(AuthenticationView) }
|
||||||
};
|
};
|
||||||
private readonly Dictionary<Type, Type> _viewViewModelBinding = new Dictionary<Type, Type>
|
|
||||||
{
|
|
||||||
{ typeof(HomeView), typeof(HomeViewModel) },
|
|
||||||
{ typeof(SettingsView), typeof(SettingsViewModel) },
|
|
||||||
{ typeof(AuthenticationView), typeof(AuthenticationViewModel) }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region METHODS
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public static IServiceProvider ServiceProvider { protected get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
{
|
{
|
||||||
@@ -42,20 +46,21 @@ namespace VDownload.GUI.Converters
|
|||||||
}
|
}
|
||||||
if (value is Type type && _viewModelViewBinding.ContainsKey(type))
|
if (value is Type type && _viewModelViewBinding.ContainsKey(type))
|
||||||
{
|
{
|
||||||
return ServiceProvider.Instance.GetService(_viewModelViewBinding[type]);
|
return ServiceProvider.GetService(_viewModelViewBinding[type]);
|
||||||
}
|
}
|
||||||
if (_viewModelViewBinding.ContainsKey(value.GetType()))
|
if (_viewModelViewBinding.ContainsKey(value.GetType()))
|
||||||
{
|
{
|
||||||
return ServiceProvider.Instance.GetService(_viewModelViewBinding[value.GetType()]);
|
return ServiceProvider.GetService(_viewModelViewBinding[value.GetType()]);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
{
|
{
|
||||||
if (_viewViewModelBinding.ContainsKey(value.GetType()))
|
Dictionary<Type, Type> viewViewModelBinding = _viewModelViewBinding.ToDictionary(x => x.Value, x => x.Key);
|
||||||
|
if (viewViewModelBinding.ContainsKey(value.GetType()))
|
||||||
{
|
{
|
||||||
return _viewViewModelBinding[value.GetType()];
|
return viewViewModelBinding[value.GetType()];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class BooleanToGridLengthConverter : IValueConverter
|
|
||||||
{
|
|
||||||
#region METHODS
|
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
GridLength notVisibleLength = new GridLength(0);
|
|
||||||
if (value is bool visible)
|
|
||||||
{
|
|
||||||
GridLength visibleLength = new GridLength(1, GridUnitType.Star);
|
|
||||||
if (parameter is string width)
|
|
||||||
{
|
|
||||||
if (width.ToLower() == "auto")
|
|
||||||
{
|
|
||||||
visibleLength = GridLength.Auto;
|
|
||||||
}
|
|
||||||
else if (int.TryParse(width, out int result))
|
|
||||||
{
|
|
||||||
visibleLength = new GridLength(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return visible ? visibleLength : notVisibleLength;
|
|
||||||
}
|
|
||||||
return notVisibleLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class BooleanToGridLengthFillConverter : IValueConverter
|
|
||||||
{
|
|
||||||
#region METHODS
|
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
GridLength falseLength = GridLength.Auto;
|
|
||||||
if (value is bool boolean)
|
|
||||||
{
|
|
||||||
GridLength trueLength = new GridLength(1, GridUnitType.Star);
|
|
||||||
return boolean ? trueLength : falseLength;
|
|
||||||
}
|
|
||||||
return falseLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class BooleanToGridLengthFillReversedConverter : IValueConverter
|
|
||||||
{
|
|
||||||
#region METHODS
|
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
GridLength falseLength = GridLength.Auto;
|
|
||||||
if (value is bool boolean)
|
|
||||||
{
|
|
||||||
GridLength trueLength = new GridLength(1, GridUnitType.Star);
|
|
||||||
return boolean ? falseLength : trueLength;
|
|
||||||
}
|
|
||||||
return falseLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class BooleanToGridLengthReversedConverter : IValueConverter
|
|
||||||
{
|
|
||||||
#region METHODS
|
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
GridLength visibleLength = new GridLength(1, GridUnitType.Star);
|
|
||||||
if (value is bool visible)
|
|
||||||
{
|
|
||||||
GridLength notVisibleLength = new GridLength(0);
|
|
||||||
if (parameter is string width)
|
|
||||||
{
|
|
||||||
if (width.ToLower() == "auto")
|
|
||||||
{
|
|
||||||
visibleLength = GridLength.Auto;
|
|
||||||
}
|
|
||||||
else if (int.TryParse(width, out int result))
|
|
||||||
{
|
|
||||||
visibleLength = new GridLength(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return visible ? notVisibleLength : visibleLength;
|
|
||||||
}
|
|
||||||
return visibleLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class BooleanToStringConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
if (value is bool boolean)
|
|
||||||
{
|
|
||||||
return boolean.ToString();
|
|
||||||
}
|
|
||||||
return bool.FalseString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
if (value is string str)
|
|
||||||
{
|
|
||||||
return str == bool.TrueString;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class BooleanToVisibilityConverter : IValueConverter
|
|
||||||
{
|
|
||||||
#region METHODS
|
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
if (value is bool isVisible)
|
|
||||||
{
|
|
||||||
return isVisible ? Visibility.Visible : Visibility.Collapsed;
|
|
||||||
}
|
|
||||||
return Visibility.Collapsed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
if (value is Visibility visibility)
|
|
||||||
{
|
|
||||||
return visibility == Visibility.Visible;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.ComponentModel.DataAnnotations;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class EnumToDescriptionConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
if (value is Enum enumValue)
|
|
||||||
{
|
|
||||||
return enumValue.GetType().GetMember(enumValue.ToString()).FirstOrDefault()?.GetCustomAttribute<DescriptionAttribute>()?.Description;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class ReverseBooleanConverter : IValueConverter
|
|
||||||
{
|
|
||||||
#region METHODS
|
|
||||||
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
if (value is bool boolean)
|
|
||||||
{
|
|
||||||
return !boolean;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language) => Convert(value, targetType, parameter, language);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class StringToLowerConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
return value.ToString().ToLower();
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class StringToUriConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
if (value is string str)
|
|
||||||
{
|
|
||||||
return new Uri(str, UriKind.RelativeOrAbsolute);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
if (value is Uri uri)
|
|
||||||
{
|
|
||||||
return uri.OriginalString;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using Microsoft.UI.Xaml;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Converters
|
|
||||||
{
|
|
||||||
public class StringToVisibilityConverter : IValueConverter
|
|
||||||
{
|
|
||||||
public object Convert(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
if (value is not string str || string.IsNullOrWhiteSpace(str))
|
|
||||||
{
|
|
||||||
return Visibility.Collapsed;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return Visibility.Visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
|
||||||
<RootNamespace>VDownload.GUI.Converters</RootNamespace>
|
|
||||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
|
||||||
<UseWinUI>true</UseWinUI>
|
|
||||||
<UseRidGraph>true</UseRidGraph>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231219000" />
|
|
||||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services\VDownload.Services.csproj" />
|
|
||||||
<ProjectReference Include="..\VDownload.GUI.ViewModels\VDownload.GUI.ViewModels.csproj" />
|
|
||||||
<ProjectReference Include="..\VDownload.GUI.Views\VDownload.GUI.Views.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Customs.Models
|
|
||||||
{
|
|
||||||
public class NavigationViewItem
|
|
||||||
{
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
public required string Name { get; init; }
|
|
||||||
public required string IconSource { get; init; }
|
|
||||||
public required Type ViewModel { get; init; }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Services.ResourceDictionaries
|
|
||||||
{
|
|
||||||
public interface IImagesResourceDictionary
|
|
||||||
{
|
|
||||||
// LOGO
|
|
||||||
string Logo { get; }
|
|
||||||
|
|
||||||
// SOURCES
|
|
||||||
string SourcesTwitch { get; }
|
|
||||||
|
|
||||||
// NAVIGATION VIEW
|
|
||||||
string NavigationViewAuthentication { get; }
|
|
||||||
string NavigationViewHome { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class ImagesResourceDictionary : IImagesResourceDictionary
|
|
||||||
{
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
// LOGO
|
|
||||||
public string Logo { get; private set; }
|
|
||||||
|
|
||||||
// SOURCES
|
|
||||||
public string SourcesTwitch { get; private set; }
|
|
||||||
|
|
||||||
// NAVIGATION VIEW
|
|
||||||
public string NavigationViewAuthentication { get; private set; }
|
|
||||||
public string NavigationViewHome { get; private set; }
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region CONSTRUCTORS
|
|
||||||
|
|
||||||
public ImagesResourceDictionary()
|
|
||||||
{
|
|
||||||
Logo = (string)Application.Current.Resources["ImageLogo"];
|
|
||||||
|
|
||||||
SourcesTwitch = (string)Application.Current.Resources["ImageSourcesTwitch"];
|
|
||||||
|
|
||||||
NavigationViewAuthentication = (string)Application.Current.Resources["ImageNavigationViewAuthentication"];
|
|
||||||
NavigationViewHome = (string)Application.Current.Resources["ImageNavigationViewHome"];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
using Microsoft.UI.Xaml;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Services.ResourceDictionaries
|
|
||||||
{
|
|
||||||
public interface IResourceDictionariesServices
|
|
||||||
{
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
IImagesResourceDictionary Images { get; }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region METHODS
|
|
||||||
|
|
||||||
T Get<T>(string key);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class ResourceDictionariesServices : IResourceDictionariesServices
|
|
||||||
{
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
public IImagesResourceDictionary Images { get; private set; }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region CONSTRUCTORS
|
|
||||||
|
|
||||||
public ResourceDictionariesServices(IImagesResourceDictionary imagesResourceDictionary)
|
|
||||||
{
|
|
||||||
Images = imagesResourceDictionary;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region PUBLIC METHODS
|
|
||||||
|
|
||||||
public T Get<T>(string key)
|
|
||||||
{
|
|
||||||
Application.Current.Resources.TryGetValue(key, out object value);
|
|
||||||
if (value is not null && value is T cast)
|
|
||||||
{
|
|
||||||
return cast;
|
|
||||||
}
|
|
||||||
throw new KeyNotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
|
||||||
<RootNamespace>VDownload.GUI.ViewModels</RootNamespace>
|
|
||||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
|
||||||
<UseWinUI>true</UseWinUI>
|
|
||||||
<UseRidGraph>true</UseRidGraph>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
|
||||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231219000" />
|
|
||||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\VDownload.Common\VDownload.Common.csproj" />
|
|
||||||
<ProjectReference Include="..\..\VDownload.Services\VDownload.Services.Search\VDownload.Services.Search.csproj" />
|
|
||||||
<ProjectReference Include="..\..\VDownload.Sources\VDownload.Sources.Twitch\VDownload.Sources.Twitch.Authentication\VDownload.Sources.Twitch.Authentication.csproj" />
|
|
||||||
<ProjectReference Include="..\..\VDownload.Sources\VDownload.Sources.Twitch\VDownload.Sources.Twitch\VDownload.Sources.Twitch.csproj" />
|
|
||||||
<ProjectReference Include="..\..\VDownload.Tasks\VDownload.Tasks.csproj" />
|
|
||||||
<ProjectReference Include="..\VDownload.GUI.Services\VDownload.GUI.Services.Dialog\VDownload.GUI.Services.Dialog.csproj" />
|
|
||||||
<ProjectReference Include="..\VDownload.GUI.Services\VDownload.GUI.Services.StoragePicker\VDownload.GUI.Services.StoragePicker.csproj" />
|
|
||||||
<ProjectReference Include="..\VDownload.GUI.Services\VDownload.GUI.Services.WebView\VDownload.GUI.Services.WebView.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices.WindowsRuntime;
|
|
||||||
using Windows.Foundation;
|
|
||||||
using Windows.Foundation.Collections;
|
|
||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Controls;
|
|
||||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
|
||||||
using Microsoft.UI.Xaml.Data;
|
|
||||||
using Microsoft.UI.Xaml.Input;
|
|
||||||
using Microsoft.UI.Xaml.Media;
|
|
||||||
using Microsoft.UI.Xaml.Navigation;
|
|
||||||
using VDownload.GUI.ViewModels;
|
|
||||||
|
|
||||||
namespace VDownload.GUI.Views
|
|
||||||
{
|
|
||||||
public sealed partial class AuthenticationView : Page
|
|
||||||
{
|
|
||||||
public AuthenticationView(AuthenticationViewModel viewModel)
|
|
||||||
{
|
|
||||||
this.InitializeComponent();
|
|
||||||
this.DataContext = viewModel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,578 +0,0 @@
|
|||||||
<Page
|
|
||||||
x:Class="VDownload.GUI.Views.HomeView"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:local="using:VDownload.GUI.Views"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:i="using:Microsoft.Xaml.Interactivity"
|
|
||||||
xmlns:ic="using:Microsoft.Xaml.Interactions.Core"
|
|
||||||
xmlns:cc="using:VDownload.GUI.Controls"
|
|
||||||
xmlns:cmn="using:VDownload.Common"
|
|
||||||
xmlns:ct="using:CommunityToolkit.WinUI"
|
|
||||||
xmlns:ctc="using:CommunityToolkit.WinUI.Controls"
|
|
||||||
xmlns:ctuc="using:CommunityToolkit.WinUI.UI.Controls"
|
|
||||||
xmlns:ctb="using:CommunityToolkit.WinUI.Behaviors"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
Background="Transparent"
|
|
||||||
x:Name="Root">
|
|
||||||
<i:Interaction.Behaviors>
|
|
||||||
<ic:EventTriggerBehavior EventName="Loaded">
|
|
||||||
<ic:InvokeCommandAction Command="{Binding NavigationCommand}"/>
|
|
||||||
</ic:EventTriggerBehavior>
|
|
||||||
</i:Interaction.Behaviors>
|
|
||||||
<Grid RowSpacing="10"
|
|
||||||
Margin="10">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<ctuc:SwitchPresenter Grid.Row="0"
|
|
||||||
Value="{Binding MainContent, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
CornerRadius="10">
|
|
||||||
<ctuc:Case Value="Downloads">
|
|
||||||
<ctuc:SwitchPresenter Value="{Binding TaskListIsEmpty, Converter={StaticResource BooleanToStringConverter}}">
|
|
||||||
<ctuc:Case Value="True">
|
|
||||||
<StackPanel HorizontalAlignment="Center"
|
|
||||||
VerticalAlignment="Center">
|
|
||||||
<Image Source="{StaticResource ImageDownloadsNoTasks}"
|
|
||||||
Width="100"/>
|
|
||||||
<TextBlock Text="Click Video/Playlist search button to add new tasks"
|
|
||||||
Foreground="{StaticResource GreyText}"/>
|
|
||||||
</StackPanel>
|
|
||||||
</ctuc:Case>
|
|
||||||
<ctuc:Case Value="False">
|
|
||||||
<ScrollViewer>
|
|
||||||
<ItemsControl ItemsSource="{Binding Tasks}">
|
|
||||||
<ItemsControl.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<Grid Background="{ThemeResource ViewBackgroundColor}"
|
|
||||||
CornerRadius="10"
|
|
||||||
Height="150">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<Image Grid.Column="0"
|
|
||||||
Source="{Binding Video.ThumbnailUrl}"
|
|
||||||
VerticalAlignment="Stretch"/>
|
|
||||||
<Grid Grid.Column="1"
|
|
||||||
Margin="10"
|
|
||||||
RowSpacing="10">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid Grid.Row="0"
|
|
||||||
ColumnSpacing="10"
|
|
||||||
HorizontalAlignment="Left">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBlock Grid.Column="0"
|
|
||||||
FontWeight="SemiBold"
|
|
||||||
FontSize="18"
|
|
||||||
Text="{Binding Video.Title}"
|
|
||||||
TextTrimming="CharacterEllipsis"/>
|
|
||||||
<TextBlock Grid.Column="1"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
FontWeight="Light"
|
|
||||||
FontSize="12"
|
|
||||||
Text="{Binding Video.Author}"/>
|
|
||||||
</Grid>
|
|
||||||
<Grid Grid.Row="1"
|
|
||||||
RowSpacing="10"
|
|
||||||
ColumnSpacing="10">
|
|
||||||
<Grid.Resources>
|
|
||||||
<x:Double x:Key="TextSize">12</x:Double>
|
|
||||||
</Grid.Resources>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<Image Grid.Row="0"
|
|
||||||
Grid.Column="0"
|
|
||||||
Source="{ThemeResource ImageDownloadsQuality}"/>
|
|
||||||
<TextBlock Grid.Row="0"
|
|
||||||
Grid.Column="1"
|
|
||||||
FontSize="{StaticResource TextSize}"
|
|
||||||
VerticalAlignment="Center">
|
|
||||||
<Run Text="{Binding MediaType, Converter={StaticResource EnumToDescriptionConverter}}"/> (<Run Text="{Binding VideoStream.StreamIdentifier}"/>)
|
|
||||||
</TextBlock>
|
|
||||||
<Image Grid.Row="1"
|
|
||||||
Grid.Column="0"
|
|
||||||
Source="{ThemeResource ImageDownloadsTime}"/>
|
|
||||||
<StackPanel Grid.Row="1"
|
|
||||||
Grid.Column="1"
|
|
||||||
Orientation="Horizontal"
|
|
||||||
VerticalAlignment="Center">
|
|
||||||
<TextBlock Text="{Binding DurationAfterTrim}"
|
|
||||||
FontSize="{StaticResource TextSize}"/>
|
|
||||||
<TextBlock Visibility="{Binding IsTrimmed, Converter={StaticResource BooleanToVisibilityConverter}}"
|
|
||||||
FontSize="{StaticResource TextSize}">
|
|
||||||
<Run Text=" "/>(<Run Text="{Binding TrimStart}"/> - <Run Text="{Binding TrimEnd}"/>)
|
|
||||||
</TextBlock>
|
|
||||||
</StackPanel>
|
|
||||||
<Image Grid.Row="2"
|
|
||||||
Grid.Column="0"
|
|
||||||
Source="{ThemeResource ImageDownloadsFile}"/>
|
|
||||||
<TextBlock Grid.Row="2"
|
|
||||||
Grid.Column="1"
|
|
||||||
FontSize="{StaticResource TextSize}"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{Binding FilePath}"/>
|
|
||||||
<Image Grid.Row="3"
|
|
||||||
Grid.Column="0">
|
|
||||||
<i:Interaction.Behaviors>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="Equal"
|
|
||||||
Value="Idle">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Source"
|
|
||||||
Value="{ThemeResource ImageDownloadsIdle}"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="Equal"
|
|
||||||
Value="Queued">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Source"
|
|
||||||
Value="{ThemeResource ImageDownloadsQueued}"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="Equal"
|
|
||||||
Value="Initializing">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Source"
|
|
||||||
Value="{ThemeResource ImageDownloadsInitializing}"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
</i:Interaction.Behaviors>
|
|
||||||
</Image>
|
|
||||||
<TextBlock Grid.Row="3"
|
|
||||||
Grid.Column="1"
|
|
||||||
FontSize="{StaticResource TextSize}"
|
|
||||||
VerticalAlignment="Center">
|
|
||||||
<i:Interaction.Behaviors>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="Equal"
|
|
||||||
Value="Idle">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Text"
|
|
||||||
Value="Idle"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="Equal"
|
|
||||||
Value="Queued">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Text"
|
|
||||||
Value="Queued"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="Equal"
|
|
||||||
Value="Initializing">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Text"
|
|
||||||
Value="Initializing"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
</i:Interaction.Behaviors>
|
|
||||||
</TextBlock>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
<Grid Grid.Column="2"
|
|
||||||
Margin="0,0,5,0">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<AppBarButton Grid.Row="0"
|
|
||||||
Width="40"
|
|
||||||
Height="48">
|
|
||||||
<i:Interaction.Behaviors>
|
|
||||||
<ic:EventTriggerBehavior EventName="Click">
|
|
||||||
<ctb:NavigateToUriAction NavigateUri="{Binding Video.Url}"/>
|
|
||||||
</ic:EventTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Video.Source, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="Equal"
|
|
||||||
Value="Twitch">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Icon">
|
|
||||||
<ic:ChangePropertyAction.Value>
|
|
||||||
<BitmapIcon ShowAsMonochrome="False"
|
|
||||||
UriSource="{StaticResource ImageSourcesTwitch}"/>
|
|
||||||
</ic:ChangePropertyAction.Value>
|
|
||||||
</ic:ChangePropertyAction>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
</i:Interaction.Behaviors>
|
|
||||||
</AppBarButton>
|
|
||||||
<AppBarButton Grid.Row="1"
|
|
||||||
Width="40"
|
|
||||||
Height="48"
|
|
||||||
Command="{Binding ElementName=Root, Path=DataContext.StartCancelTaskCommand}"
|
|
||||||
CommandParameter="{Binding}">
|
|
||||||
<i:Interaction.Behaviors>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToIntConverter}}"
|
|
||||||
ComparisonCondition="LessThan"
|
|
||||||
Value="4">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Icon">
|
|
||||||
<ic:ChangePropertyAction.Value>
|
|
||||||
<SymbolIcon Symbol="Download"/>
|
|
||||||
</ic:ChangePropertyAction.Value>
|
|
||||||
</ic:ChangePropertyAction>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToIntConverter}}"
|
|
||||||
ComparisonCondition="GreaterThanOrEqual"
|
|
||||||
Value="4">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Icon">
|
|
||||||
<ic:ChangePropertyAction.Value>
|
|
||||||
<SymbolIcon Symbol="Cancel"/>
|
|
||||||
</ic:ChangePropertyAction.Value>
|
|
||||||
</ic:ChangePropertyAction>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
</i:Interaction.Behaviors>
|
|
||||||
</AppBarButton>
|
|
||||||
<AppBarButton Grid.Row="2"
|
|
||||||
Icon="Delete"
|
|
||||||
Width="40"
|
|
||||||
Height="48"/>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
<ProgressBar Grid.Row="1"
|
|
||||||
Value="{Binding Progress}">
|
|
||||||
<i:Interaction.Behaviors>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToIntConverter}}"
|
|
||||||
ComparisonCondition="LessThan"
|
|
||||||
Value="5">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Visibility" Value="Collapsed"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToIntConverter}}"
|
|
||||||
ComparisonCondition="GreaterThanOrEqual"
|
|
||||||
Value="5">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Visibility" Value="Visible"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToIntConverter}}"
|
|
||||||
ComparisonCondition="LessThan"
|
|
||||||
Value="7">
|
|
||||||
<ic:ChangePropertyAction PropertyName="IsIndeterminate" Value="True"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Status, Converter={StaticResource EnumToIntConverter}}"
|
|
||||||
ComparisonCondition="GreaterThanOrEqual"
|
|
||||||
Value="7">
|
|
||||||
<ic:ChangePropertyAction PropertyName="IsIndeterminate" Value="False"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
</i:Interaction.Behaviors>
|
|
||||||
</ProgressBar>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
</DataTemplate>
|
|
||||||
</ItemsControl.ItemTemplate>
|
|
||||||
</ItemsControl>
|
|
||||||
</ScrollViewer>
|
|
||||||
</ctuc:Case>
|
|
||||||
</ctuc:SwitchPresenter>
|
|
||||||
</ctuc:Case>
|
|
||||||
<ctuc:Case Value="Video">
|
|
||||||
<Grid Padding="15"
|
|
||||||
RowSpacing="20"
|
|
||||||
Background="{ThemeResource ViewBackgroundColor}">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="150"/>
|
|
||||||
<RowDefinition/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Grid Grid.Row="0"
|
|
||||||
ColumnSpacing="10">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition Width="*"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<Border Grid.Column="0"
|
|
||||||
CornerRadius="{ThemeResource ControlCornerRadius}">
|
|
||||||
<Image Source="{Binding Task.Video.ThumbnailUrl}"
|
|
||||||
VerticalAlignment="Stretch"/>
|
|
||||||
</Border>
|
|
||||||
<StackPanel Grid.Column="1"
|
|
||||||
Spacing="15">
|
|
||||||
<TextBlock Text="{Binding Task.Video.Title}"
|
|
||||||
FontWeight="Bold"
|
|
||||||
FontSize="20"
|
|
||||||
TextWrapping="WrapWholeWords"/>
|
|
||||||
<Grid ColumnSpacing="10"
|
|
||||||
RowSpacing="10">
|
|
||||||
<Grid.Resources>
|
|
||||||
<x:Double x:Key="IconSize">18</x:Double>
|
|
||||||
</Grid.Resources>
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
<RowDefinition Height="Auto"/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<Image Grid.Column="0"
|
|
||||||
Grid.Row="0"
|
|
||||||
Source="{ThemeResource ImageVideoAuthor}"
|
|
||||||
Width="{StaticResource IconSize}"/>
|
|
||||||
<TextBlock Grid.Column="1"
|
|
||||||
Grid.Row="0"
|
|
||||||
Text="{Binding Task.Video.Author}"/>
|
|
||||||
<Image Grid.Column="0"
|
|
||||||
Grid.Row="1"
|
|
||||||
Source="{ThemeResource ImageVideoDate}"
|
|
||||||
Width="{StaticResource IconSize}"/>
|
|
||||||
<TextBlock Grid.Column="1"
|
|
||||||
Grid.Row="1"
|
|
||||||
Text="{Binding Task.Video.PublishDate}"/>
|
|
||||||
<Image Grid.Column="0"
|
|
||||||
Grid.Row="2"
|
|
||||||
Source="{ThemeResource ImageVideoTime}"
|
|
||||||
Width="{StaticResource IconSize}"/>
|
|
||||||
<TextBlock Grid.Column="1"
|
|
||||||
Grid.Row="2"
|
|
||||||
Text="{Binding Task.Video.Duration}"/>
|
|
||||||
<Image Grid.Column="0"
|
|
||||||
Grid.Row="3"
|
|
||||||
Source="{ThemeResource ImageVideoView}"
|
|
||||||
Width="{StaticResource IconSize}"/>
|
|
||||||
<TextBlock Grid.Column="1"
|
|
||||||
Grid.Row="3"
|
|
||||||
Text="{Binding Task.Video.ViewCount}"/>
|
|
||||||
</Grid>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
<ScrollViewer Grid.Row="1">
|
|
||||||
<StackPanel Spacing="20">
|
|
||||||
<StackPanel Spacing="5">
|
|
||||||
<TextBlock Text="Media options"
|
|
||||||
FontWeight="Bold"
|
|
||||||
FontSize="15"/>
|
|
||||||
<ctc:SettingsCard Header="Quality">
|
|
||||||
<ctc:SettingsCard.HeaderIcon>
|
|
||||||
<BitmapIcon ShowAsMonochrome="False"
|
|
||||||
UriSource="{ThemeResource ImageVideoQuality}"/>
|
|
||||||
</ctc:SettingsCard.HeaderIcon>
|
|
||||||
<ComboBox ItemsSource="{Binding Task.Video.Streams}"
|
|
||||||
SelectedItem="{Binding Task.VideoStream, Mode=TwoWay}">
|
|
||||||
<ComboBox.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<TextBlock Text="{Binding StreamIdentifier}"/>
|
|
||||||
</DataTemplate>
|
|
||||||
</ComboBox.ItemTemplate>
|
|
||||||
</ComboBox>
|
|
||||||
</ctc:SettingsCard>
|
|
||||||
<ctc:SettingsCard Header="Media type">
|
|
||||||
<ctc:SettingsCard.HeaderIcon>
|
|
||||||
<BitmapIcon ShowAsMonochrome="False"
|
|
||||||
UriSource="{ThemeResource ImageVideoMedia}"/>
|
|
||||||
</ctc:SettingsCard.HeaderIcon>
|
|
||||||
<ComboBox ItemsSource="{ct:EnumValues Type=cmn:MediaType}"
|
|
||||||
SelectedItem="{Binding Task.MediaType, Mode=TwoWay}">
|
|
||||||
<ComboBox.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<TextBlock Text="{Binding Converter={StaticResource EnumToDescriptionConverter}}"/>
|
|
||||||
</DataTemplate>
|
|
||||||
</ComboBox.ItemTemplate>
|
|
||||||
</ComboBox>
|
|
||||||
</ctc:SettingsCard>
|
|
||||||
<ctc:SettingsExpander Header="Trim">
|
|
||||||
<ctc:SettingsExpander.HeaderIcon>
|
|
||||||
<BitmapIcon ShowAsMonochrome="False"
|
|
||||||
UriSource="{ThemeResource ImageVideoTrim}"/>
|
|
||||||
</ctc:SettingsExpander.HeaderIcon>
|
|
||||||
<ctc:SettingsExpander.Items>
|
|
||||||
<ctc:SettingsCard Header="Start at">
|
|
||||||
<cc:TimeSpanControl Value="{Binding Task.TrimStart, Mode=TwoWay}"
|
|
||||||
Maximum="{Binding Task.TrimEnd, Mode=OneWay}"/>
|
|
||||||
</ctc:SettingsCard>
|
|
||||||
<ctc:SettingsCard Header="End at">
|
|
||||||
<cc:TimeSpanControl Minimum="{Binding Task.TrimStart, Mode=OneWay}"
|
|
||||||
Value="{Binding Task.TrimEnd, Mode=TwoWay}"
|
|
||||||
Maximum="{Binding Task.Video.Duration, Mode=OneWay}"/>
|
|
||||||
</ctc:SettingsCard>
|
|
||||||
</ctc:SettingsExpander.Items>
|
|
||||||
</ctc:SettingsExpander>
|
|
||||||
</StackPanel>
|
|
||||||
<StackPanel Spacing="5">
|
|
||||||
<TextBlock Text="File options"
|
|
||||||
FontWeight="Bold"
|
|
||||||
FontSize="15"/>
|
|
||||||
<ctc:SettingsCard Header="Directory"
|
|
||||||
Description="{Binding Task.DirectoryPath}">
|
|
||||||
<ctc:SettingsCard.HeaderIcon>
|
|
||||||
<BitmapIcon ShowAsMonochrome="False" UriSource="{ThemeResource ImageVideoDirectory}"/>
|
|
||||||
</ctc:SettingsCard.HeaderIcon>
|
|
||||||
<Button Content="Browse"
|
|
||||||
Command="{Binding BrowseCommand}"/>
|
|
||||||
</ctc:SettingsCard>
|
|
||||||
<ctc:SettingsCard Header="Filename">
|
|
||||||
<ctc:SettingsCard.HeaderIcon>
|
|
||||||
<BitmapIcon ShowAsMonochrome="False" UriSource="{ThemeResource ImageVideoFilename}"/>
|
|
||||||
</ctc:SettingsCard.HeaderIcon>
|
|
||||||
<TextBox Text="{Binding Task.Filename, Mode=TwoWay}"/>
|
|
||||||
</ctc:SettingsCard>
|
|
||||||
<ctc:SettingsCard Header="File type"
|
|
||||||
Description="If original video is not in selected type, it will be converted">
|
|
||||||
<ctc:SettingsCard.HeaderIcon>
|
|
||||||
<BitmapIcon ShowAsMonochrome="False" UriSource="{ThemeResource ImageVideoExtension}"/>
|
|
||||||
</ctc:SettingsCard.HeaderIcon>
|
|
||||||
<ComboBox>
|
|
||||||
<i:Interaction.Behaviors>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Task.MediaType, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="Equal"
|
|
||||||
Value="OnlyAudio">
|
|
||||||
<ic:ChangePropertyAction PropertyName="ItemsSource"
|
|
||||||
Value="{ct:EnumValues Type=cmn:AudioExtension}"/>
|
|
||||||
<ic:ChangePropertyAction PropertyName="SelectedItem"
|
|
||||||
Value="{Binding Task.AudioExtension}"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding Task.MediaType, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="NotEqual"
|
|
||||||
Value="OnlyAudio">
|
|
||||||
<ic:ChangePropertyAction PropertyName="ItemsSource"
|
|
||||||
Value="{ct:EnumValues Type=cmn:VideoExtension}"/>
|
|
||||||
<ic:ChangePropertyAction PropertyName="SelectedItem"
|
|
||||||
Value="{Binding Task.VideoExtension}"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
</i:Interaction.Behaviors>
|
|
||||||
<ComboBox.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<TextBlock Text="{Binding}"/>
|
|
||||||
</DataTemplate>
|
|
||||||
</ComboBox.ItemTemplate>
|
|
||||||
</ComboBox>
|
|
||||||
</ctc:SettingsCard>
|
|
||||||
</StackPanel>
|
|
||||||
</StackPanel>
|
|
||||||
</ScrollViewer>
|
|
||||||
<Button Grid.Row="2"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Style="{StaticResource AccentButtonStyle}"
|
|
||||||
Content="Create download task"
|
|
||||||
Command="{Binding CreateTaskCommand}"/>
|
|
||||||
</Grid>
|
|
||||||
</ctuc:Case>
|
|
||||||
</ctuc:SwitchPresenter>
|
|
||||||
<Grid Grid.Row="1"
|
|
||||||
Background="{ThemeResource OptionBarBackgroundColor}"
|
|
||||||
CornerRadius="10">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition Width="50"/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<ctuc:UniformGrid Grid.Column="0"
|
|
||||||
Rows="1"
|
|
||||||
Margin="15,0,0,0">
|
|
||||||
<ctuc:UniformGrid.RowDefinitions>
|
|
||||||
<RowDefinition/>
|
|
||||||
</ctuc:UniformGrid.RowDefinitions>
|
|
||||||
<ctuc:UniformGrid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</ctuc:UniformGrid.ColumnDefinitions>
|
|
||||||
<ctuc:SwitchPresenter Grid.Row="0"
|
|
||||||
VerticalAlignment="Stretch"
|
|
||||||
Margin="0,0,15,0"
|
|
||||||
Value="{Binding OptionBarContent, Converter={StaticResource EnumToStringConverter}}">
|
|
||||||
<i:Interaction.Behaviors>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding OptionBarContent, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="Equal"
|
|
||||||
Value="None">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Visibility"
|
|
||||||
Value="Collapsed"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
<ic:DataTriggerBehavior Binding="{Binding OptionBarContent, Converter={StaticResource EnumToStringConverter}}"
|
|
||||||
ComparisonCondition="NotEqual"
|
|
||||||
Value="None">
|
|
||||||
<ic:ChangePropertyAction PropertyName="Visibility"
|
|
||||||
Value="Visible"/>
|
|
||||||
</ic:DataTriggerBehavior>
|
|
||||||
</i:Interaction.Behaviors>
|
|
||||||
<ctuc:Case Value="VideoSearch">
|
|
||||||
<Grid ColumnSpacing="10"
|
|
||||||
VerticalAlignment="Stretch">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBox Grid.Column="0"
|
|
||||||
PlaceholderText="Video URL"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
Text="{Binding OptionBarVideoSearchTBValue, Mode=TwoWay}"/>
|
|
||||||
<Button Grid.Column="1"
|
|
||||||
Content="Search"
|
|
||||||
IsEnabled="{Binding OptionBarSearchNotPending}"
|
|
||||||
Command="{Binding VideoSearchStartCommand}"/>
|
|
||||||
</Grid>
|
|
||||||
</ctuc:Case>
|
|
||||||
<ctuc:Case Value="PlaylistSearch">
|
|
||||||
<Grid ColumnSpacing="10">
|
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
<ColumnDefinition Width="Auto"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
<TextBox Grid.Column="0"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
PlaceholderText="Playlist URL"
|
|
||||||
Text="{Binding OptionBarPlaylistSearchTBValue, Mode=TwoWay}"/>
|
|
||||||
<NumberBox Grid.Column="1"
|
|
||||||
VerticalAlignment="Center"
|
|
||||||
SpinButtonPlacementMode="Compact"
|
|
||||||
SmallChange="1"
|
|
||||||
LargeChange="10"
|
|
||||||
Value="{Binding OptionBarPlaylistSearchNBValue, Mode=TwoWay}"
|
|
||||||
Minimum="1"
|
|
||||||
ToolTipService.ToolTip="Number of videos to get from playlist"/>
|
|
||||||
<Button Grid.Column="2"
|
|
||||||
Content="Search"
|
|
||||||
IsEnabled="{Binding OptionBarSearchNotPending}"
|
|
||||||
Command="{Binding PlaylistSearchStartCommand}"/>
|
|
||||||
</Grid>
|
|
||||||
</ctuc:Case>
|
|
||||||
</ctuc:SwitchPresenter>
|
|
||||||
<StackPanel VerticalAlignment="Center"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<ProgressRing Width="20"
|
|
||||||
Height="20"
|
|
||||||
Margin="0,0,10,0"
|
|
||||||
Visibility="{Binding OptionBarLoading, Converter={StaticResource BooleanToVisibilityConverter}}"/>
|
|
||||||
<TextBlock Text="{Binding OptionBarMessage}"/>
|
|
||||||
</StackPanel>
|
|
||||||
</ctuc:UniformGrid>
|
|
||||||
<StackPanel Grid.Column="2"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<AppBarButton Width="150"
|
|
||||||
Label="Load from subscriptions"
|
|
||||||
Icon="Favorite"
|
|
||||||
IsEnabled="{Binding OptionBarSearchNotPending}"
|
|
||||||
Command="{Binding LoadFromSubscriptionCommand}"/>
|
|
||||||
<AppBarToggleButton Label="Video search"
|
|
||||||
Width="100"
|
|
||||||
Icon="Video"
|
|
||||||
IsEnabled="{Binding OptionBarSearchNotPending}"
|
|
||||||
IsChecked="{Binding OptionBarVideoSearchButtonChecked, Mode=TwoWay}"
|
|
||||||
Command="{Binding VideoSearchShowCommand}"/>
|
|
||||||
<AppBarToggleButton Label="Playlist search"
|
|
||||||
Width="100"
|
|
||||||
Icon="List"
|
|
||||||
IsEnabled="{Binding OptionBarSearchNotPending}"
|
|
||||||
IsChecked="{Binding OptionBarPlaylistSearchButtonChecked, Mode=TwoWay}"
|
|
||||||
Command="{Binding PlaylistSearchShowCommand}"/>
|
|
||||||
<AppBarSeparator/>
|
|
||||||
<AppBarButton Width="100"
|
|
||||||
Label="Download all"
|
|
||||||
Icon="Download"
|
|
||||||
Command="{Binding DownloadCommand}"/>
|
|
||||||
</StackPanel>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</Page>
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
|
||||||
<RootNamespace>VDownload.GUI.Views</RootNamespace>
|
|
||||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
|
||||||
<UseWinUI>true</UseWinUI>
|
|
||||||
<UseRidGraph>true</UseRidGraph>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Remove="AuthenticationView.xaml" />
|
|
||||||
<None Remove="HomeView.xaml" />
|
|
||||||
<None Remove="SettingsView.xaml" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
|
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Behaviors" Version="8.0.240109" />
|
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.0.240109" />
|
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" Version="8.0.240109" />
|
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
|
|
||||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231219000" />
|
|
||||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
|
||||||
<PackageReference Include="Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.0.9" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\VDownload.GUI.Controls\VDownload.GUI.Controls.csproj" />
|
|
||||||
<ProjectReference Include="..\VDownload.GUI.Customs\VDownload.GUI.Customs.csproj" />
|
|
||||||
<ProjectReference Include="..\VDownload.GUI.ViewModels\VDownload.GUI.ViewModels.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Page Update="AuthenticationView.xaml">
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Page Update="SettingsView.xaml">
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Page Update="HomeView.xaml">
|
|
||||||
<Generator>MSBuild:Compile</Generator>
|
|
||||||
</Page>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -4,10 +4,13 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.Common
|
namespace VDownload.Models
|
||||||
{
|
{
|
||||||
public enum AudioExtension
|
public enum AudioExtension
|
||||||
{
|
{
|
||||||
MP3
|
MP3,
|
||||||
|
FLAC,
|
||||||
|
WAV,
|
||||||
|
OGG
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.Common
|
namespace VDownload.Models
|
||||||
{
|
{
|
||||||
public enum MediaType
|
public enum MediaType
|
||||||
{
|
{
|
||||||
@@ -4,10 +4,9 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.Common
|
namespace VDownload.Models
|
||||||
{
|
{
|
||||||
public enum VideoExtension
|
public abstract class Playlist
|
||||||
{
|
{
|
||||||
MP4
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
21
VDownload.Models/ProcessingSpeed.cs
Normal file
21
VDownload.Models/ProcessingSpeed.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Models
|
||||||
|
{
|
||||||
|
public enum ProcessingSpeed
|
||||||
|
{
|
||||||
|
VerySlow = 0,
|
||||||
|
Slower = 1,
|
||||||
|
Slow = 2,
|
||||||
|
Medium = 3,
|
||||||
|
Fast = 4,
|
||||||
|
Faster = 5,
|
||||||
|
VeryFast = 6,
|
||||||
|
SuperFast = 7,
|
||||||
|
UltraFast = 8
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.Common
|
namespace VDownload.Models
|
||||||
{
|
{
|
||||||
public enum Source
|
public enum Source
|
||||||
{
|
{
|
||||||
37
VDownload.Models/Video.cs
Normal file
37
VDownload.Models/Video.cs
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Models
|
||||||
|
{
|
||||||
|
public abstract class Video
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Author { get; set; }
|
||||||
|
public DateTime PublishDate { get; set; }
|
||||||
|
public TimeSpan Duration { get; set; }
|
||||||
|
public long Views { get; set; }
|
||||||
|
public Uri ThumbnailUrl { get; set; }
|
||||||
|
public ICollection<VideoStream> Streams { get; set; }
|
||||||
|
public Uri Url { get; set; }
|
||||||
|
public Source Source { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
protected Video()
|
||||||
|
{
|
||||||
|
Streams = new List<VideoStream>();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
44
VDownload.Models/VideoDownloadOptions.cs
Normal file
44
VDownload.Models/VideoDownloadOptions.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Models
|
||||||
|
{
|
||||||
|
public class VideoDownloadOptions
|
||||||
|
{
|
||||||
|
#region FIELDS
|
||||||
|
|
||||||
|
private readonly TimeSpan _originalDuration;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public required VideoStream SelectedStream { get; set; }
|
||||||
|
public required TimeSpan TrimStart { get; set; }
|
||||||
|
public required TimeSpan TrimEnd { get; set; }
|
||||||
|
public required MediaType MediaType { get; set; }
|
||||||
|
public required string Directory { get; set; }
|
||||||
|
public required string Filename { get; set; }
|
||||||
|
public required string Extension { get; set; }
|
||||||
|
public TimeSpan DurationAfterTrim => TrimEnd - TrimStart;
|
||||||
|
public bool IsTrimmed => _originalDuration != DurationAfterTrim;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public VideoDownloadOptions(TimeSpan originalDuration)
|
||||||
|
{
|
||||||
|
_originalDuration = originalDuration;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
18
VDownload.Models/VideoExtension.cs
Normal file
18
VDownload.Models/VideoExtension.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Models
|
||||||
|
{
|
||||||
|
public enum VideoExtension
|
||||||
|
{
|
||||||
|
MP4,
|
||||||
|
MKV,
|
||||||
|
AVI,
|
||||||
|
MOV,
|
||||||
|
WEBM,
|
||||||
|
WMV,
|
||||||
|
}
|
||||||
|
}
|
||||||
27
VDownload.Models/VideoStream.cs
Normal file
27
VDownload.Models/VideoStream.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Models
|
||||||
|
{
|
||||||
|
public abstract class VideoStream
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public override string ToString() => Name;
|
||||||
|
|
||||||
|
public abstract Task<VideoStreamDownloadResult> Download(string taskTemporaryDirectory, IProgress<double> onProgress, CancellationToken token, TimeSpan trimStart, TimeSpan trimEnd);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
20
VDownload.Models/VideoStreamDownloadResult.cs
Normal file
20
VDownload.Models/VideoStreamDownloadResult.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Models
|
||||||
|
{
|
||||||
|
public struct VideoStreamDownloadResult
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public required string File { get; init; }
|
||||||
|
public required TimeSpan NewTrimStart { get; init; }
|
||||||
|
public required TimeSpan NewTrimEnd { get; init; }
|
||||||
|
public required TimeSpan NewDuration { get; init; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.Services.Authentication
|
|
||||||
{
|
|
||||||
public class AuthenticationConfiguration
|
|
||||||
{
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
public string FilePath { get; private set; }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region CONSTRUCTORS
|
|
||||||
|
|
||||||
public AuthenticationConfiguration(IConfiguration configuration)
|
|
||||||
{
|
|
||||||
IConfigurationSection section = configuration.GetSection("authentication");
|
|
||||||
FilePath = section["file_path"];
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace VDownload.Services.Authentication
|
|
||||||
{
|
|
||||||
public class AuthenticationData
|
|
||||||
{
|
|
||||||
#region PROPERTY
|
|
||||||
|
|
||||||
[JsonProperty("twitch")]
|
|
||||||
public AuthenticationDataTwitch Twitch { get; internal set; }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region CONSTRUCTORS
|
|
||||||
|
|
||||||
public AuthenticationData()
|
|
||||||
{
|
|
||||||
Twitch = new AuthenticationDataTwitch();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
using Newtonsoft.Json;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using VDownload.Extensions;
|
|
||||||
|
|
||||||
namespace VDownload.Services.Authentication
|
|
||||||
{
|
|
||||||
public interface IAuthenticationService
|
|
||||||
{
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
AuthenticationData? AuthenticationData { get; }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region METHODS
|
|
||||||
|
|
||||||
Task Load();
|
|
||||||
Task Save();
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class AuthenticationService : IAuthenticationService
|
|
||||||
{
|
|
||||||
#region SERVICES
|
|
||||||
|
|
||||||
private AuthenticationConfiguration _configuration;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region FIELDS
|
|
||||||
|
|
||||||
private string _authenticationDataFile;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
public AuthenticationData AuthenticationData { get; private set; }
|
|
||||||
|
|
||||||
public bool AuthenticationDataLoaded => AuthenticationData is not null;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region CONSTRUCTORS
|
|
||||||
|
|
||||||
public AuthenticationService(AuthenticationConfiguration configuration)
|
|
||||||
{
|
|
||||||
_configuration = configuration;
|
|
||||||
|
|
||||||
_authenticationDataFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), _configuration.FilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region PUBLIC METHODS
|
|
||||||
|
|
||||||
public async Task Load()
|
|
||||||
{
|
|
||||||
AuthenticationData = null;
|
|
||||||
|
|
||||||
if (File.Exists(_authenticationDataFile))
|
|
||||||
{
|
|
||||||
string content = await File.ReadAllTextAsync(_authenticationDataFile);
|
|
||||||
AuthenticationData = JsonConvert.DeserializeObject<AuthenticationData>(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
AuthenticationData ??= new AuthenticationData();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Save()
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(_authenticationDataFile));
|
|
||||||
string content = JsonConvert.SerializeObject(AuthenticationData);
|
|
||||||
await File.WriteAllTextAsync(_authenticationDataFile, content);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using VDownload.Services.Data.Authentication.Models;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Authentication
|
||||||
|
{
|
||||||
|
public class AuthenticationData
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonProperty("twitch")]
|
||||||
|
public TokenAuthenticationData Twitch { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public AuthenticationData()
|
||||||
|
{
|
||||||
|
Twitch = new TokenAuthenticationData();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Services.Data.Configuration;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Authentication
|
||||||
|
{
|
||||||
|
public interface IAuthenticationDataService
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
AuthenticationData Data { get; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region METHODS
|
||||||
|
|
||||||
|
Task Load();
|
||||||
|
Task Save();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AuthenticationDataService : IAuthenticationDataService
|
||||||
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
protected readonly IConfigurationService _configurationService;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region FIELDS
|
||||||
|
|
||||||
|
protected readonly string _filePath;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public AuthenticationData Data { get; protected set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public AuthenticationDataService(IConfigurationService configurationService)
|
||||||
|
{
|
||||||
|
_configurationService = configurationService;
|
||||||
|
|
||||||
|
string appdataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||||
|
string appdataDirectoryName = _configurationService.Common.Path.Appdata.DirectoryName;
|
||||||
|
string appdataAuthenticationFilename = _configurationService.Common.Path.Appdata.AuthenticationFile;
|
||||||
|
_filePath = Path.Combine(appdataPath, appdataDirectoryName, appdataAuthenticationFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public async Task Load()
|
||||||
|
{
|
||||||
|
Data = null;
|
||||||
|
|
||||||
|
if (File.Exists(_filePath))
|
||||||
|
{
|
||||||
|
string content = await File.ReadAllTextAsync(_filePath);
|
||||||
|
Data = JsonConvert.DeserializeObject<AuthenticationData>(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
Data ??= new AuthenticationData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Save()
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(_filePath));
|
||||||
|
string content = JsonConvert.SerializeObject(Data);
|
||||||
|
await File.WriteAllTextAsync(_filePath, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,9 +5,9 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.Services.Authentication
|
namespace VDownload.Services.Data.Authentication.Models
|
||||||
{
|
{
|
||||||
public class AuthenticationDataTwitch
|
public class TokenAuthenticationData
|
||||||
{
|
{
|
||||||
[JsonProperty("token")]
|
[JsonProperty("token")]
|
||||||
public byte[]? Token { get; set; }
|
public byte[]? Token { get; set; }
|
||||||
@@ -7,12 +7,11 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\VDownload.Extensions\VDownload.Extensions.csproj" />
|
<ProjectReference Include="..\VDownload.Services.Data.Configuration\VDownload.Services.Data.Configuration.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using VDownload.Services.Data.Configuration.Models;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Configuration
|
||||||
|
{
|
||||||
|
public class CommonConfiguration
|
||||||
|
{
|
||||||
|
[ConfigurationKeyName("path")]
|
||||||
|
public Models.Path Path { get; set; }
|
||||||
|
|
||||||
|
[ConfigurationKeyName("processing")]
|
||||||
|
public Processing Processing { get; set; }
|
||||||
|
|
||||||
|
[ConfigurationKeyName("string_resources_assembly")]
|
||||||
|
public string StringResourcesAssembly { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Sources.Twitch.Configuration;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Configuration
|
||||||
|
{
|
||||||
|
public interface IConfigurationService
|
||||||
|
{
|
||||||
|
CommonConfiguration Common { get; }
|
||||||
|
TwitchConfiguration Twitch { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class ConfigurationService : IConfigurationService
|
||||||
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
protected readonly IConfiguration _configuration;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public CommonConfiguration Common { get; protected set; }
|
||||||
|
public TwitchConfiguration Twitch { get; protected set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public ConfigurationService(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
Common = configuration.GetSection("common").Get<CommonConfiguration>()!;
|
||||||
|
Twitch = configuration.GetSection("twitch").Get<TwitchConfiguration>()!;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Configuration.Models
|
||||||
|
{
|
||||||
|
public class Appdata
|
||||||
|
{
|
||||||
|
[ConfigurationKeyName("directory_name")]
|
||||||
|
public string DirectoryName { get; set; }
|
||||||
|
|
||||||
|
[ConfigurationKeyName("authentication_file")]
|
||||||
|
public string AuthenticationFile { get; set; }
|
||||||
|
|
||||||
|
[ConfigurationKeyName("settings_file")]
|
||||||
|
public string SettingsFile { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Configuration.Models
|
||||||
|
{
|
||||||
|
public class Muxer
|
||||||
|
{
|
||||||
|
[ConfigurationKeyName("extension")]
|
||||||
|
public string Extension { get; set; }
|
||||||
|
|
||||||
|
[ConfigurationKeyName("video_codecs")]
|
||||||
|
public List<string> VideoCodecs { get; } = new List<string>();
|
||||||
|
|
||||||
|
[ConfigurationKeyName("audio_codecs")]
|
||||||
|
public List<string> AudioCodecs { get; } = new List<string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Configuration.Models
|
||||||
|
{
|
||||||
|
public class Path
|
||||||
|
{
|
||||||
|
[ConfigurationKeyName("appdata")]
|
||||||
|
public Appdata Appdata { get; set; }
|
||||||
|
|
||||||
|
[ConfigurationKeyName("temp")]
|
||||||
|
public Temp Temp { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Configuration.Models
|
||||||
|
{
|
||||||
|
public class Processing
|
||||||
|
{
|
||||||
|
[ConfigurationKeyName("muxers")]
|
||||||
|
public List<Muxer> Muxers { get; } = new List<Muxer>();
|
||||||
|
|
||||||
|
[ConfigurationKeyName("processed_filename")]
|
||||||
|
public string ProcessedFilename { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Configuration.Models
|
||||||
|
{
|
||||||
|
public class Temp
|
||||||
|
{
|
||||||
|
[ConfigurationKeyName("tasks_directory")]
|
||||||
|
public string TasksDirectory { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\VDownload.Sources\VDownload.Sources.Twitch\VDownload.Sources.Twitch.Configuration\VDownload.Sources.Twitch.Configuration.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Models;
|
||||||
|
using VDownload.Services.Data.Settings.Models;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Settings
|
||||||
|
{
|
||||||
|
public class CommonSettings
|
||||||
|
{
|
||||||
|
[JsonProperty("max_number_of_videos_to_get_from_playlist")]
|
||||||
|
public int MaxNumberOfVideosToGetFromPlaylist { get; set; } = 0;
|
||||||
|
|
||||||
|
[JsonProperty("max_number_of_running_tasks")]
|
||||||
|
public int MaxNumberOfRunningTasks { get; set; } = 5;
|
||||||
|
|
||||||
|
[JsonProperty("temp_directory")]
|
||||||
|
public string TempDirectory { get; set; } = $"{Path.GetTempPath()}\\VDownload";
|
||||||
|
|
||||||
|
[JsonProperty("delete_temp_on_error")]
|
||||||
|
public bool DeleteTempOnError { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty("default_task_settings")]
|
||||||
|
public DefaultTaskSettings DefaultTaskSettings { get; set; } = new DefaultTaskSettings();
|
||||||
|
|
||||||
|
[JsonProperty("notifications")]
|
||||||
|
public Notifications Notifications { get; set; } = new Notifications();
|
||||||
|
|
||||||
|
[JsonProperty("processing")]
|
||||||
|
public Processing Processing { get; set; } = new Processing();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Models;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Settings.Models
|
||||||
|
{
|
||||||
|
public class DefaultTaskSettings
|
||||||
|
{
|
||||||
|
[JsonProperty("media_type")]
|
||||||
|
public MediaType MediaType { get; set; } = MediaType.Original;
|
||||||
|
|
||||||
|
[JsonProperty("video_extension")]
|
||||||
|
public VideoExtension VideoExtension { get; set; } = VideoExtension.MP4;
|
||||||
|
|
||||||
|
[JsonProperty("audio_extension")]
|
||||||
|
public AudioExtension AudioExtension { get; set; } = AudioExtension.MP3;
|
||||||
|
|
||||||
|
[JsonProperty("output_directory")]
|
||||||
|
public string OutputDirectory { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
|
||||||
|
|
||||||
|
[JsonProperty("save_last_output_directory")]
|
||||||
|
public bool SaveLastOutputDirectory { get; set; } = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Settings.Models
|
||||||
|
{
|
||||||
|
public class Notifications
|
||||||
|
{
|
||||||
|
[JsonProperty("on_successful")]
|
||||||
|
public bool OnSuccessful { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty("on_unsuccessful")]
|
||||||
|
public bool OnUnsuccessful { get; set; } = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Models;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Settings.Models
|
||||||
|
{
|
||||||
|
public class Processing
|
||||||
|
{
|
||||||
|
[JsonProperty("ffmpeg_location")]
|
||||||
|
public string FFmpegLocation { get; set; } = $"{AppDomain.CurrentDomain.BaseDirectory}\\FFmpeg";
|
||||||
|
|
||||||
|
[JsonProperty("use_multithreading")]
|
||||||
|
public bool UseMultithreading { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty("use_hardware_acceleration")]
|
||||||
|
public bool UseHardwareAcceleration { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonProperty("speed")]
|
||||||
|
public ProcessingSpeed Speed { get; set; } = ProcessingSpeed.UltraFast;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using VDownload.Sources.Twitch.Settings;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Settings
|
||||||
|
{
|
||||||
|
public class SettingsData
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
[JsonProperty("common")]
|
||||||
|
public CommonSettings Common { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("twitch")]
|
||||||
|
public TwitchSettings Twitch { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
internal SettingsData()
|
||||||
|
{
|
||||||
|
Common = new CommonSettings();
|
||||||
|
Twitch = new TwitchSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using VDownload.Services.Data.Configuration;
|
||||||
|
|
||||||
|
namespace VDownload.Services.Data.Settings
|
||||||
|
{
|
||||||
|
public interface ISettingsService
|
||||||
|
{
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
SettingsData Data { get; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region METHODS
|
||||||
|
|
||||||
|
Task Load();
|
||||||
|
Task Save();
|
||||||
|
Task Restore();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class SettingsService : ISettingsService
|
||||||
|
{
|
||||||
|
#region SERVICES
|
||||||
|
|
||||||
|
protected readonly IConfigurationService _configurationService;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region FIELDS
|
||||||
|
|
||||||
|
protected readonly string _filePath;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PROPERTIES
|
||||||
|
|
||||||
|
public SettingsData Data { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public SettingsService(IConfigurationService configurationService)
|
||||||
|
{
|
||||||
|
_configurationService = configurationService;
|
||||||
|
|
||||||
|
string appdataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
|
||||||
|
string appdataDirectoryName = _configurationService.Common.Path.Appdata.DirectoryName;
|
||||||
|
string appdataAuthenticationFilename = _configurationService.Common.Path.Appdata.SettingsFile;
|
||||||
|
_filePath = Path.Combine(appdataPath, appdataDirectoryName, appdataAuthenticationFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public async Task Load()
|
||||||
|
{
|
||||||
|
Data = null;
|
||||||
|
|
||||||
|
if (File.Exists(_filePath))
|
||||||
|
{
|
||||||
|
string content = await File.ReadAllTextAsync(_filePath);
|
||||||
|
Data = JsonConvert.DeserializeObject<SettingsData>(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
Data ??= new SettingsData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Save()
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(_filePath));
|
||||||
|
string content = JsonConvert.SerializeObject(Data);
|
||||||
|
await File.WriteAllTextAsync(_filePath, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Restore()
|
||||||
|
{
|
||||||
|
Data = new SettingsData();
|
||||||
|
await Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\VDownload.Models\VDownload.Models.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\VDownload.Sources\VDownload.Sources.Twitch\VDownload.Sources.Twitch.Settings\VDownload.Sources.Twitch.Settings.csproj" />
|
||||||
|
<ProjectReference Include="..\VDownload.Services.Data.Configuration\VDownload.Services.Data.Configuration.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\VDownload.Common\VDownload.Common.csproj" />
|
|
||||||
<ProjectReference Include="..\..\VDownload.Sources\VDownload.Sources.Twitch\VDownload.Sources.Twitch.Search\VDownload.Sources.Twitch.Search.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using VDownload.Common;
|
|
||||||
|
|
||||||
namespace VDownload.Services.Tasks
|
|
||||||
{
|
|
||||||
public interface ITasksService
|
|
||||||
{
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
ObservableCollection<DownloadTask> Tasks { get; }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region METHODS
|
|
||||||
|
|
||||||
void AddTask(DownloadTask task);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class TasksService : ITasksService
|
|
||||||
{
|
|
||||||
#region FIELDS
|
|
||||||
|
|
||||||
private readonly Task _taskMonitor;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region PROPERTIES
|
|
||||||
|
|
||||||
public ObservableCollection<DownloadTask> Tasks { get; protected set; }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region CONSTRUCTORS
|
|
||||||
|
|
||||||
public TasksService()
|
|
||||||
{
|
|
||||||
Tasks = new ObservableCollection<DownloadTask>();
|
|
||||||
|
|
||||||
_taskMonitor = Task.Run(TaskMonitor);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region PUBLIC METHODS
|
|
||||||
|
|
||||||
public void AddTask(DownloadTask task)
|
|
||||||
{
|
|
||||||
Tasks.Add(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region PRIVATE METHODS
|
|
||||||
|
|
||||||
private void TaskMonitor()
|
|
||||||
{
|
|
||||||
int maxTaskNumber = 5; //TODO: from settings
|
|
||||||
DownloadTaskStatus[] pendingStatuses =
|
|
||||||
[
|
|
||||||
DownloadTaskStatus.Initializing,
|
|
||||||
DownloadTaskStatus.Downloading,
|
|
||||||
DownloadTaskStatus.Processing,
|
|
||||||
DownloadTaskStatus.Finalizing
|
|
||||||
];
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
IEnumerable<DownloadTask> pendingTasks = Tasks.Where(x => pendingStatuses.Contains(x.Status));
|
|
||||||
int freeSlots = maxTaskNumber - pendingTasks.Count();
|
|
||||||
if (freeSlots > 0)
|
|
||||||
{
|
|
||||||
IEnumerable<DownloadTask> queuedTasks = Tasks.Where(x => x.Status == DownloadTaskStatus.Queued).OrderBy(x => x.CreateDate).Take(freeSlots);
|
|
||||||
foreach (DownloadTask queuedTask in queuedTasks)
|
|
||||||
{
|
|
||||||
queuedTask.Start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.GUI.Services.Dialog
|
namespace VDownload.Services.UI.Dialogs
|
||||||
{
|
{
|
||||||
public enum DialogResult
|
public enum DialogResult
|
||||||
{
|
{
|
||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.GUI.Services.Dialog
|
namespace VDownload.Services.UI.Dialogs
|
||||||
{
|
{
|
||||||
public enum DialogResultOkCancel
|
public enum DialogResultOkCancel
|
||||||
{
|
{
|
||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.GUI.Services.Dialog
|
namespace VDownload.Services.UI.Dialogs
|
||||||
{
|
{
|
||||||
public enum DialogResultYesNo
|
public enum DialogResultYesNo
|
||||||
{
|
{
|
||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.GUI.Services.Dialog
|
namespace VDownload.Services.UI.Dialogs
|
||||||
{
|
{
|
||||||
public enum DialogResultYesNoCancel
|
public enum DialogResultYesNoCancel
|
||||||
{
|
{
|
||||||
@@ -7,9 +7,9 @@ using System.Runtime.CompilerServices;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace VDownload.GUI.Services.Dialog
|
namespace VDownload.Services.UI.Dialogs
|
||||||
{
|
{
|
||||||
public interface IDialogService
|
public interface IDialogsService
|
||||||
{
|
{
|
||||||
#region PROPERTIES
|
#region PROPERTIES
|
||||||
|
|
||||||
@@ -35,7 +35,7 @@ namespace VDownload.GUI.Services.Dialog
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class DialogService : IDialogService
|
public class DialogsService : IDialogsService
|
||||||
{
|
{
|
||||||
#region PROPERTIES
|
#region PROPERTIES
|
||||||
|
|
||||||
@@ -2,14 +2,14 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
|
||||||
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
|
||||||
<RootNamespace>VDownload.GUI.Services.ResourceDictionaries</RootNamespace>
|
<RootNamespace>VDownload.Services.UI.Dialogs</RootNamespace>
|
||||||
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win10-x86;win10-x64;win10-arm64</RuntimeIdentifiers>
|
||||||
<UseWinUI>true</UseWinUI>
|
<UseWinUI>true</UseWinUI>
|
||||||
<UseRidGraph>true</UseRidGraph>
|
<UseRidGraph>true</UseRidGraph>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231219000" />
|
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.240211001" />
|
||||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace VDownload.Services.UI.DictionaryResources
|
||||||
|
{
|
||||||
|
public interface IDictionaryResourcesService
|
||||||
|
{
|
||||||
|
T Get<T>(string key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class DictionaryResourcesService : IDictionaryResourcesService
|
||||||
|
{
|
||||||
|
#region CONSTRUCTORS
|
||||||
|
|
||||||
|
public DictionaryResourcesService() { }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#region PUBLIC METHODS
|
||||||
|
|
||||||
|
public T Get<T>(string key)
|
||||||
|
{
|
||||||
|
Application.Current.Resources.TryGetValue(key, out object value);
|
||||||
|
if (value is not null && value is T cast)
|
||||||
|
{
|
||||||
|
return cast;
|
||||||
|
}
|
||||||
|
throw new KeyNotFoundException();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user