Added base decoding logic + notification logic.
This commit is contained in:
@@ -55,6 +55,9 @@
|
|||||||
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
<ApplicationIcon>favicon.ico</ApplicationIcon>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Reference Include="DotNetDBF, Version=6.0.0.3, Culture=neutral, PublicKeyToken=9c071727b589770e, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\DotNetDBF.6.0.0.3\lib\net35\DotNetDBF.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Firebase.Auth, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Firebase.Auth, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\FirebaseAuthentication.net.3.4.0\lib\netstandard1.1\Firebase.Auth.dll</HintPath>
|
<HintPath>..\packages\FirebaseAuthentication.net.3.4.0\lib\netstandard1.1\Firebase.Auth.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
@@ -267,7 +270,12 @@
|
|||||||
<Compile Include="Utils\CIECAMonitor.cs">
|
<Compile Include="Utils\CIECAMonitor.cs">
|
||||||
<SubType>Component</SubType>
|
<SubType>Component</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Utils\Decoder\EstimateDecoder.cs" />
|
||||||
<Compile Include="Utils\GraphQL.cs" />
|
<Compile Include="Utils\GraphQL.cs" />
|
||||||
|
<Compile Include="Utils\Growls\GrowlNotification.xaml.cs">
|
||||||
|
<DependentUpon>GrowlNotification.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Utils\Growls\Notification.cs" />
|
||||||
<Compile Include="Utils\JobProcessingQueue.cs" />
|
<Compile Include="Utils\JobProcessingQueue.cs" />
|
||||||
<Compile Include="Utils\LoginHelpers.cs" />
|
<Compile Include="Utils\LoginHelpers.cs" />
|
||||||
<Compile Include="Utils\RelayCommand.cs" />
|
<Compile Include="Utils\RelayCommand.cs" />
|
||||||
@@ -288,6 +296,10 @@
|
|||||||
<Compile Include="Views\Main.xaml.cs">
|
<Compile Include="Views\Main.xaml.cs">
|
||||||
<DependentUpon>Main.xaml</DependentUpon>
|
<DependentUpon>Main.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Page Include="Utils\Growls\GrowlNotification.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="Views\Login.xaml">
|
<Page Include="Views\Login.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ namespace BodyshopUploader.Models
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private dynamic _job;
|
||||||
|
public dynamic Job
|
||||||
|
{
|
||||||
|
get { return _job; }
|
||||||
|
set { SetProperty(ref _job, value); }
|
||||||
|
}
|
||||||
|
|
||||||
private string _filePath;
|
private string _filePath;
|
||||||
public string FilePath
|
public string FilePath
|
||||||
{
|
{
|
||||||
|
|||||||
249
BodyshopUploader/Utils/Decoder/EstimateDecoder.cs
Normal file
249
BodyshopUploader/Utils/Decoder/EstimateDecoder.cs
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DotNetDBF;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
|
namespace BodyshopUploader.Utils.Decoder
|
||||||
|
{
|
||||||
|
class EstimateDecoder
|
||||||
|
{
|
||||||
|
public static class CIECAEstimateImport
|
||||||
|
{
|
||||||
|
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decode the set of estimate files based on the creation of an envelope file.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="FilePath">Full path to the envelope file that was created/updated.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static dynamic DecodeEstimate(string FilePath)
|
||||||
|
{
|
||||||
|
//Sleep the thread so that all files can finish writing.
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
dynamic ret = new JObject();
|
||||||
|
|
||||||
|
ret.CiecaId = Path.GetFileNameWithoutExtension(FilePath);
|
||||||
|
|
||||||
|
string _dir = Path.GetDirectoryName(FilePath) + @"\";
|
||||||
|
|
||||||
|
ParseAd1File(ref ret, _dir);
|
||||||
|
ParseVehFile(ref ret, _dir);
|
||||||
|
ParseStlFile(ref ret, _dir);
|
||||||
|
ParseTtlFile(ref ret, _dir);
|
||||||
|
ParseLinFile(ref ret, _dir);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ParseAd1File(ref dynamic j, string RootFilePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(j.CiecaId.Value))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logger.Trace(@"Parsing AD1 at: {0}{1}", RootFilePath, j.CiecaId.Value);
|
||||||
|
|
||||||
|
int retryNumber = 0;
|
||||||
|
while (retryNumber < 11)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + "A.ad1", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||||
|
{
|
||||||
|
var reader = new DBFReader(fis);
|
||||||
|
reader.SetSelectFields(new string[] { "INS_CO_NM", "CLM_NO", "OWNR_LN", "OWNR_FN", "OWNR_EA", "OWNR_PH1" });
|
||||||
|
var readValues = reader.NextRecord();
|
||||||
|
j.Claim_Source = readValues[0].ToString();
|
||||||
|
j.Claim_Number = readValues[1].ToString();
|
||||||
|
j.Owner_Ln = readValues[2].ToString();
|
||||||
|
j.Owner_Fn = readValues[3].ToString();
|
||||||
|
j.Owner_Email = readValues[4].ToString();
|
||||||
|
j.Owner_Phone = readValues[5].ToString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
logger.Trace(ex, "Unable to open AD1 file. Retrying. ");
|
||||||
|
retryNumber++;
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ParseVehFile(ref dynamic j, string RootFilePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; }
|
||||||
|
|
||||||
|
logger.Trace(@"Parsing Veh at: {0}{1}", RootFilePath, j.CiecaId.Value);
|
||||||
|
|
||||||
|
int retryNumber = 0;
|
||||||
|
while (retryNumber < 11)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + "v.veh", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||||
|
{
|
||||||
|
var reader = new DBFReader(fis);
|
||||||
|
reader.SetSelectFields(new string[] { "V_MODEL_YR", "V_MAKEDESC", "V_MODEL", "V_COLOR", "PLATE_NO", "V_VIN" });
|
||||||
|
var readValues = reader.NextRecord();
|
||||||
|
j.V_Model_Yr = readValues[0].ToString();
|
||||||
|
j.V_Make_Desc = readValues[1].ToString();
|
||||||
|
j.V_Model = readValues[2].ToString();
|
||||||
|
j.V_Color = readValues[3].ToString();
|
||||||
|
j.Lic_Plate = readValues[4].ToString();
|
||||||
|
j.V_Vin = readValues[5].ToString();
|
||||||
|
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
logger.Trace(ex, "Unable to open VEH file. Retrying. ");
|
||||||
|
retryNumber++;
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ParseTtlFile(ref dynamic j, string RootFilePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; }
|
||||||
|
|
||||||
|
logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.CiecaId.Value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int retryNumber = 0;
|
||||||
|
while (retryNumber < 11)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + ".ttl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||||
|
{
|
||||||
|
var reader = new DBFReader(fis);
|
||||||
|
reader.SetSelectFields(new string[] { "G_TTL_AMT" });
|
||||||
|
var readValues = reader.NextRecord();
|
||||||
|
j.Claim_Total = Convert.ToDecimal(readValues[0].ToString());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
logger.Trace(ex, "Unable to open TTL file. Retrying. ");
|
||||||
|
retryNumber++;
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ParseStlFile(ref dynamic j, string RootFilePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; }
|
||||||
|
|
||||||
|
logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.CiecaId.Value);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int retryNumber = 0;
|
||||||
|
while (retryNumber < 11)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + ".stl", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||||
|
{
|
||||||
|
var reader = new DBFReader(fis);
|
||||||
|
reader.SetSelectFields(new string[] { "TTL_TYPECD", "T_HRS" });
|
||||||
|
var _rc = reader.RecordCount;
|
||||||
|
for (var i = 0; i < _rc; i++)
|
||||||
|
{
|
||||||
|
var readValues = reader.NextRecord();
|
||||||
|
switch (readValues[0])
|
||||||
|
{
|
||||||
|
|
||||||
|
//Labor Code
|
||||||
|
case "LAB":
|
||||||
|
j.BodyHrs = Convert.ToDecimal(readValues[1]);
|
||||||
|
break;
|
||||||
|
case "LAR":
|
||||||
|
j.RefHrs = Convert.ToDecimal(readValues[1]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
logger.Trace(ex, "Unable to open STL file. Retrying. ");
|
||||||
|
retryNumber++;
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void ParseLinFile(ref dynamic j, string RootFilePath)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(j.CiecaId.Value)) { return; }
|
||||||
|
|
||||||
|
logger.Trace(@"Parsing Ttl at: {0}{1}", RootFilePath, j.CiecaId.Value);
|
||||||
|
//j.JobSublets = new List<JobSublet>();
|
||||||
|
|
||||||
|
string _maxSupp = "";
|
||||||
|
|
||||||
|
int retryNumber = 0;
|
||||||
|
while (retryNumber < 11)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using (Stream fis = File.Open(RootFilePath + j.CiecaId.Value + ".lin", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||||
|
{
|
||||||
|
var reader = new DBFReader(fis);
|
||||||
|
reader.SetSelectFields(new string[] { "PART_TYPE", "LINE_DESC", "UNQ_SEQ", "LINE_IND" });
|
||||||
|
var _rc = reader.RecordCount;
|
||||||
|
for (var i = 0; i < _rc; i++)
|
||||||
|
{
|
||||||
|
var readValues = reader.NextRecord();
|
||||||
|
//Find Max Supplement Number
|
||||||
|
if (string.Compare(_maxSupp, readValues[3].ToString()) < 0)
|
||||||
|
{
|
||||||
|
_maxSupp = readValues[3].ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (readValues[3])
|
||||||
|
{
|
||||||
|
|
||||||
|
//Labor Code
|
||||||
|
case "PAS":
|
||||||
|
case "PASL":
|
||||||
|
//j.JobSublets.Add(new JobSublet()
|
||||||
|
//{
|
||||||
|
// SubletDesc = readValues[1].ToString(),
|
||||||
|
// Unq_Seq = Convert.ToInt32(readValues[2])
|
||||||
|
//});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
j.MaxSupplement = _maxSupp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
logger.Trace(ex, "Unable to open LIN file. Retrying. ");
|
||||||
|
retryNumber++;
|
||||||
|
Thread.Sleep(3000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
178
BodyshopUploader/Utils/Growls/GrowlNotification.xaml
Normal file
178
BodyshopUploader/Utils/Growls/GrowlNotification.xaml
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
<Window x:Class="BodyshopUploader.Utils.Growls.GrowlNotification"
|
||||||
|
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:local="clr-namespace:BodyshopUploader.Utils.Growls"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
SizeToContent="WidthAndHeight"
|
||||||
|
|
||||||
|
AllowsTransparency="True"
|
||||||
|
WindowStyle="None"
|
||||||
|
ShowInTaskbar="False"
|
||||||
|
Topmost="True"
|
||||||
|
UseLayoutRounding="True"
|
||||||
|
|
||||||
|
Title="BodyshopUploader Notification"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
|
||||||
|
TextElement.FontWeight="Regular"
|
||||||
|
TextElement.FontSize="13"
|
||||||
|
TextOptions.TextFormattingMode="Ideal"
|
||||||
|
TextOptions.TextRenderingMode="Auto"
|
||||||
|
Background="Transparent"
|
||||||
|
FontFamily="{DynamicResource MaterialDesignFont}">
|
||||||
|
<Window.Resources>
|
||||||
|
<Storyboard x:Key="CollapseStoryboard">
|
||||||
|
<DoubleAnimation From="100"
|
||||||
|
To="0"
|
||||||
|
Storyboard.TargetProperty="Height"
|
||||||
|
Duration="0:0:0.5" />
|
||||||
|
</Storyboard>
|
||||||
|
<DataTemplate x:Key="MessageTemplate"
|
||||||
|
DataType="Model:Notification">
|
||||||
|
<Grid x:Name="NotificationWindow"
|
||||||
|
Tag="{Binding Path=Id}"
|
||||||
|
MouseLeftButtonDown="NotificationWindow_MouseLeftButtonDown"
|
||||||
|
Background="Transparent"
|
||||||
|
SizeChanged="NotificationWindowSizeChanged">
|
||||||
|
<Border Name="border"
|
||||||
|
Background="#2a3345"
|
||||||
|
BorderThickness="0"
|
||||||
|
CornerRadius="10"
|
||||||
|
Margin="10">
|
||||||
|
<Border.Effect>
|
||||||
|
<DropShadowEffect ShadowDepth="0"
|
||||||
|
Opacity="0.8"
|
||||||
|
BlurRadius="10" />
|
||||||
|
</Border.Effect>
|
||||||
|
<Grid Height="100"
|
||||||
|
Width="380"
|
||||||
|
Margin="6">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"></RowDefinition>
|
||||||
|
<RowDefinition Height="Auto"></RowDefinition>
|
||||||
|
<RowDefinition Height="*"></RowDefinition>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"></ColumnDefinition>
|
||||||
|
<ColumnDefinition Width="*"></ColumnDefinition>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Image Grid.RowSpan="2"
|
||||||
|
Source="../../favicon.ico"
|
||||||
|
Margin="4"
|
||||||
|
Width="24"></Image>
|
||||||
|
<TextBlock Grid.Column="1"
|
||||||
|
Text="{Binding Path=Title}"
|
||||||
|
TextOptions.TextRenderingMode="ClearType"
|
||||||
|
TextOptions.TextFormattingMode="Display"
|
||||||
|
Foreground="White"
|
||||||
|
FontFamily="Arial"
|
||||||
|
FontSize="14"
|
||||||
|
FontWeight="Bold"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="2,4,4,2"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
TextTrimming="CharacterEllipsis" />
|
||||||
|
<!--<Button x:Name="CloseButton" Grid.Column="1" Width="16" Height="16" HorizontalAlignment="Right" Margin="0,0,12,0" />-->
|
||||||
|
|
||||||
|
<Button x:Name="CloseButton"
|
||||||
|
Grid.Column="1"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Width="24"
|
||||||
|
Height="24">
|
||||||
|
<materialDesign:PackIcon Kind="Close"
|
||||||
|
Height="16"
|
||||||
|
Width="16" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="1"
|
||||||
|
Grid.Column="1"
|
||||||
|
Text="{Binding Path=Subtitle}"
|
||||||
|
TextOptions.TextRenderingMode="ClearType"
|
||||||
|
TextOptions.TextFormattingMode="Display"
|
||||||
|
Foreground="White"
|
||||||
|
FontFamily="Arial"
|
||||||
|
FontSize="14"
|
||||||
|
FontWeight="Bold"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="2,4,4,2"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
TextTrimming="CharacterEllipsis" />
|
||||||
|
<TextBlock Grid.Row="2"
|
||||||
|
Grid.Column="1"
|
||||||
|
Text="{Binding Path=Message}"
|
||||||
|
TextOptions.TextRenderingMode="ClearType"
|
||||||
|
TextOptions.TextFormattingMode="Display"
|
||||||
|
Foreground="White"
|
||||||
|
FontFamily="Arial"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="2,2,4,4"
|
||||||
|
TextWrapping="Wrap"
|
||||||
|
TextTrimming="CharacterEllipsis" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
<DataTemplate.Triggers>
|
||||||
|
<EventTrigger RoutedEvent="Window.Loaded"
|
||||||
|
SourceName="NotificationWindow">
|
||||||
|
<BeginStoryboard x:Name="FadeInStoryBoard">
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="NotificationWindow"
|
||||||
|
From="0.01"
|
||||||
|
To="1"
|
||||||
|
Storyboard.TargetProperty="Opacity"
|
||||||
|
Duration="0:0:1" />
|
||||||
|
<DoubleAnimation Storyboard.TargetName="NotificationWindow"
|
||||||
|
From="1"
|
||||||
|
To="0"
|
||||||
|
Storyboard.TargetProperty="Opacity"
|
||||||
|
Duration="0:0:2"
|
||||||
|
BeginTime="0:0:3" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</EventTrigger>
|
||||||
|
<Trigger Property="IsMouseOver"
|
||||||
|
Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<SeekStoryboard Offset="0:0:1"
|
||||||
|
BeginStoryboardName="FadeInStoryBoard" />
|
||||||
|
<PauseStoryboard BeginStoryboardName="FadeInStoryBoard" />
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<SeekStoryboard Offset="0:0:1"
|
||||||
|
BeginStoryboardName="FadeInStoryBoard" />
|
||||||
|
<ResumeStoryboard BeginStoryboardName="FadeInStoryBoard"></ResumeStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
<EventTrigger RoutedEvent="Button.Click"
|
||||||
|
SourceName="CloseButton">
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetName="NotificationWindow"
|
||||||
|
From="1"
|
||||||
|
To="0"
|
||||||
|
Storyboard.TargetProperty="(Grid.Opacity)"
|
||||||
|
Duration="0:0:0" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</EventTrigger>
|
||||||
|
<Trigger SourceName="NotificationWindow"
|
||||||
|
Property="Opacity"
|
||||||
|
Value="0">
|
||||||
|
<Setter TargetName="NotificationWindow"
|
||||||
|
Property="Visibility"
|
||||||
|
Value="Hidden"></Setter>
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard Storyboard="{StaticResource CollapseStoryboard}" />
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
</Trigger>
|
||||||
|
</DataTemplate.Triggers>
|
||||||
|
</DataTemplate>
|
||||||
|
</Window.Resources>
|
||||||
|
<ItemsControl x:Name="NotificationsControl"
|
||||||
|
FocusVisualStyle="{x:Null}"
|
||||||
|
ItemsSource="{Binding .}"
|
||||||
|
ItemTemplate="{StaticResource MessageTemplate}" />
|
||||||
|
</Window>
|
||||||
91
BodyshopUploader/Utils/Growls/GrowlNotification.xaml.cs
Normal file
91
BodyshopUploader/Utils/Growls/GrowlNotification.xaml.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
|
||||||
|
namespace BodyshopUploader.Utils.Growls
|
||||||
|
{
|
||||||
|
public partial class GrowlNotification
|
||||||
|
{
|
||||||
|
private const byte MAX_NOTIFICATIONS = 4;
|
||||||
|
private int count;
|
||||||
|
public Notifications Notifications = new Notifications();
|
||||||
|
private readonly Notifications buffer = new Notifications();
|
||||||
|
public ViewModels.MainViewModel ShellVm;
|
||||||
|
public GrowlNotification(ViewModels.MainViewModel shellViewModel)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
ShellVm = shellViewModel;
|
||||||
|
NotificationsControl.DataContext = Notifications;
|
||||||
|
var desktopWorkingArea = System.Windows.SystemParameters.WorkArea;
|
||||||
|
this.Left = desktopWorkingArea.Right - 425;
|
||||||
|
//this.Top = desktopWorkingArea.Bottom - 425;
|
||||||
|
this.Top = 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddNotification(Notification notification)
|
||||||
|
{
|
||||||
|
notification.Id = count++;
|
||||||
|
if (Notifications.Count + 1 > MAX_NOTIFICATIONS)
|
||||||
|
buffer.Add(notification);
|
||||||
|
else
|
||||||
|
Notifications.Add(notification);
|
||||||
|
//Show window if there're notifications
|
||||||
|
if (Notifications.Count > 0 && !IsActive)
|
||||||
|
Show();
|
||||||
|
}
|
||||||
|
public void RemoveNotification(Notification notification)
|
||||||
|
{
|
||||||
|
if (Notifications.Contains(notification))
|
||||||
|
Notifications.Remove(notification);
|
||||||
|
if (buffer.Count > 0)
|
||||||
|
{
|
||||||
|
Notifications.Add(buffer[0]);
|
||||||
|
buffer.RemoveAt(0);
|
||||||
|
}
|
||||||
|
//Close window if there's nothing to show
|
||||||
|
if (Notifications.Count < 1)
|
||||||
|
Hide();
|
||||||
|
}
|
||||||
|
private void NotificationWindowSizeChanged(object sender, SizeChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.NewSize.Height != 0.0)
|
||||||
|
return;
|
||||||
|
var element = sender as Grid;
|
||||||
|
RemoveNotification(Notifications.First(
|
||||||
|
n => n.Id == Int32.Parse(element.Tag.ToString())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NotificationWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
Notification n = (Notification)((Grid)sender).DataContext;
|
||||||
|
BringWindowToFront();
|
||||||
|
RemoveNotification(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BringWindowToFront()
|
||||||
|
{
|
||||||
|
var currentProcess = Process.GetCurrentProcess();
|
||||||
|
var processes = Process.GetProcessesByName(currentProcess.ProcessName);
|
||||||
|
var process = processes.FirstOrDefault(p => p.Id == currentProcess.Id);
|
||||||
|
if (process == null) return;
|
||||||
|
|
||||||
|
SetForegroundWindow(process.MainWindowHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
static extern bool SetForegroundWindow(IntPtr hWnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
102
BodyshopUploader/Utils/Growls/Notification.cs
Normal file
102
BodyshopUploader/Utils/Growls/Notification.cs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BodyshopUploader.Utils.Growls
|
||||||
|
{
|
||||||
|
public class Notification : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
private string message;
|
||||||
|
public string Message
|
||||||
|
{
|
||||||
|
get { return message; }
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (message == value) return;
|
||||||
|
message = value;
|
||||||
|
OnPropertyChanged("Message");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
public int Id
|
||||||
|
{
|
||||||
|
get { return id; }
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (id == value) return;
|
||||||
|
id = value;
|
||||||
|
OnPropertyChanged("Id");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int threadid;
|
||||||
|
public int ThreadId
|
||||||
|
{
|
||||||
|
get { return threadid; }
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (threadid == value) return;
|
||||||
|
threadid = value;
|
||||||
|
OnPropertyChanged("ThreadId");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string imageUrl;
|
||||||
|
public string ImageUrl
|
||||||
|
{
|
||||||
|
get { return imageUrl; }
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (imageUrl == value) return;
|
||||||
|
imageUrl = value;
|
||||||
|
OnPropertyChanged("ImageUrl");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private string title;
|
||||||
|
public string Title
|
||||||
|
{
|
||||||
|
get { return title; }
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (title == value) return;
|
||||||
|
title = value;
|
||||||
|
OnPropertyChanged("Title");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string subtitle;
|
||||||
|
public string Subtitle
|
||||||
|
{
|
||||||
|
get { return subtitle; }
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (subtitle == value) return;
|
||||||
|
subtitle = value;
|
||||||
|
OnPropertyChanged("Subtitle");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnPropertyChanged(string propertyName)
|
||||||
|
{
|
||||||
|
var handler = PropertyChanged;
|
||||||
|
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Notifications : ObservableCollection<Notification> { }
|
||||||
|
}
|
||||||
@@ -57,9 +57,7 @@ namespace BodyshopUploader.Utils
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Thread.Sleep(1000);//Allow a small amount of time to pass before processing the queue item so that any writes can finish.
|
Thread.Sleep(1000);//Allow a small amount of time to pass before processing the queue item so that any writes can finish.
|
||||||
|
|
||||||
DecodeQueueItemJob(item);
|
DecodeQueueItemJob(item);
|
||||||
|
|
||||||
UpsertQueueItem(item);
|
UpsertQueueItem(item);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
@@ -74,12 +72,13 @@ namespace BodyshopUploader.Utils
|
|||||||
{
|
{
|
||||||
//Process the job.
|
//Process the job.
|
||||||
logger.Info("Should process the job here. {0}", item.FilePath);
|
logger.Info("Should process the job here. {0}", item.FilePath);
|
||||||
|
item.Job = Utils.Decoder.EstimateDecoder.CIECAEstimateImport.DecodeEstimate(item.FilePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpsertQueueItem(DTO_QueueItem item)
|
private static void UpsertQueueItem(DTO_QueueItem item)
|
||||||
{
|
{
|
||||||
//Save the job to the DB.
|
//Save the job to the DB.
|
||||||
logger.Info("Should upsert the job graphqlly here. {0}", item.FilePath);
|
logger.Info("Should upsert the job graphqlly here. {0}", item.Job);
|
||||||
|
|
||||||
_jobs.Dequeue();
|
_jobs.Dequeue();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace BodyshopUploader.ViewModels
|
|||||||
if (_removeMonitoringPathCommand == null)
|
if (_removeMonitoringPathCommand == null)
|
||||||
{
|
{
|
||||||
_removeMonitoringPathCommand = new RelayCommand(
|
_removeMonitoringPathCommand = new RelayCommand(
|
||||||
p => true,
|
p => FolderMonitors.Count == 0,
|
||||||
p => RemoveFolderMonitoringPath(p as string)
|
p => RemoveFolderMonitoringPath(p as string)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using GraphQL.Client;
|
using BodyshopUploader.Utils.Growls;
|
||||||
|
using GraphQL.Client;
|
||||||
using GraphQL.Common.Request;
|
using GraphQL.Common.Request;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -17,6 +18,7 @@ namespace BodyshopUploader.ViewModels
|
|||||||
public MainViewModel()
|
public MainViewModel()
|
||||||
{
|
{
|
||||||
logger.Trace("Main VM Created.");
|
logger.Trace("Main VM Created.");
|
||||||
|
Growler = new GrowlNotification(this);
|
||||||
|
|
||||||
//Create Variables
|
//Create Variables
|
||||||
if (MonitoringPaths == null) MonitoringPaths = new ObservableCollection<string>();
|
if (MonitoringPaths == null) MonitoringPaths = new ObservableCollection<string>();
|
||||||
@@ -75,6 +77,17 @@ namespace BodyshopUploader.ViewModels
|
|||||||
|
|
||||||
public async Task TestGql()
|
public async Task TestGql()
|
||||||
{
|
{
|
||||||
|
Notification _n = new Notification()
|
||||||
|
{
|
||||||
|
Id = 123,
|
||||||
|
ThreadId = 123,
|
||||||
|
Title = "This is a title",
|
||||||
|
Subtitle = "Subtitle",
|
||||||
|
Message = "Somethin"
|
||||||
|
};
|
||||||
|
Growler.AddNotification(_n);
|
||||||
|
|
||||||
|
|
||||||
var r = new GraphQLRequest
|
var r = new GraphQLRequest
|
||||||
{
|
{
|
||||||
Query = @"
|
Query = @"
|
||||||
|
|||||||
@@ -4,17 +4,13 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using BodyshopUploader.Utils.Growls;
|
||||||
|
|
||||||
namespace BodyshopUploader.ViewModels
|
namespace BodyshopUploader.ViewModels
|
||||||
{
|
{
|
||||||
public partial class MainViewModel : BaseViewModel
|
public partial class MainViewModel : BaseViewModel
|
||||||
{
|
{
|
||||||
private int _progress = 5;
|
public GrowlNotification Growler;
|
||||||
public int Progress
|
|
||||||
{
|
|
||||||
get { return _progress; }
|
|
||||||
set { SetProperty(ref _progress, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
private ObservableCollection<Utils.CIECAMonitor> _folderMonitors = new ObservableCollection<Utils.CIECAMonitor>() ;
|
private ObservableCollection<Utils.CIECAMonitor> _folderMonitors = new ObservableCollection<Utils.CIECAMonitor>() ;
|
||||||
public ObservableCollection<Utils.CIECAMonitor> FolderMonitors
|
public ObservableCollection<Utils.CIECAMonitor> FolderMonitors
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
|
<package id="DotNetDBF" version="6.0.0.3" targetFramework="net472" />
|
||||||
<package id="FirebaseAuthentication.net" version="3.4.0" targetFramework="net472" />
|
<package id="FirebaseAuthentication.net" version="3.4.0" targetFramework="net472" />
|
||||||
<package id="GraphQL.Client" version="1.0.3" targetFramework="net472" />
|
<package id="GraphQL.Client" version="1.0.3" targetFramework="net472" />
|
||||||
<package id="GraphQL.Common" version="1.0.3" targetFramework="net472" />
|
<package id="GraphQL.Common" version="1.0.3" targetFramework="net472" />
|
||||||
|
|||||||
Reference in New Issue
Block a user