Add project files.
commit
c91bde761e
|
@ -0,0 +1,63 @@
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior to automatically normalize line endings.
|
||||||
|
###############################################################################
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior for command prompt diff.
|
||||||
|
#
|
||||||
|
# This is need for earlier builds of msysgit that does not have it on by
|
||||||
|
# default for csharp files.
|
||||||
|
# Note: This is only used by command line
|
||||||
|
###############################################################################
|
||||||
|
#*.cs diff=csharp
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set the merge driver for project and solution files
|
||||||
|
#
|
||||||
|
# Merging from the command prompt will add diff markers to the files if there
|
||||||
|
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||||
|
# the diff markers are never inserted). Diff markers may cause the following
|
||||||
|
# file extensions to fail to load in VS. An alternative would be to treat
|
||||||
|
# these files as binary and thus will always conflict and require user
|
||||||
|
# intervention with every merge. To do so, just uncomment the entries below
|
||||||
|
###############################################################################
|
||||||
|
#*.sln merge=binary
|
||||||
|
#*.csproj merge=binary
|
||||||
|
#*.vbproj merge=binary
|
||||||
|
#*.vcxproj merge=binary
|
||||||
|
#*.vcproj merge=binary
|
||||||
|
#*.dbproj merge=binary
|
||||||
|
#*.fsproj merge=binary
|
||||||
|
#*.lsproj merge=binary
|
||||||
|
#*.wixproj merge=binary
|
||||||
|
#*.modelproj merge=binary
|
||||||
|
#*.sqlproj merge=binary
|
||||||
|
#*.wwaproj merge=binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# behavior for image files
|
||||||
|
#
|
||||||
|
# image files are treated as binary by default.
|
||||||
|
###############################################################################
|
||||||
|
#*.jpg binary
|
||||||
|
#*.png binary
|
||||||
|
#*.gif binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# diff behavior for common document formats
|
||||||
|
#
|
||||||
|
# Convert binary document formats to text before diffing them. This feature
|
||||||
|
# is only available from the command line. Turn it on by uncommenting the
|
||||||
|
# entries below.
|
||||||
|
###############################################################################
|
||||||
|
#*.doc diff=astextplain
|
||||||
|
#*.DOC diff=astextplain
|
||||||
|
#*.docx diff=astextplain
|
||||||
|
#*.DOCX diff=astextplain
|
||||||
|
#*.dot diff=astextplain
|
||||||
|
#*.DOT diff=astextplain
|
||||||
|
#*.pdf diff=astextplain
|
||||||
|
#*.PDF diff=astextplain
|
||||||
|
#*.rtf diff=astextplain
|
||||||
|
#*.RTF diff=astextplain
|
|
@ -0,0 +1,340 @@
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUNIT
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# JustCode is a .NET coding add-in
|
||||||
|
.JustCode
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- Backup*.rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
.idea/
|
||||||
|
*.sln.iml
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.29613.14
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlixP", "PlixP\PlixP.csproj", "{D97DA4A8-8F8C-4A43-A868-69912C04BEE7}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{D97DA4A8-8F8C-4A43-A868-69912C04BEE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{D97DA4A8-8F8C-4A43-A868-69912C04BEE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{D97DA4A8-8F8C-4A43-A868-69912C04BEE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{D97DA4A8-8F8C-4A43-A868-69912C04BEE7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {17816672-B5D2-4079-83EA-D88ABDD69DEE}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,2 @@
|
||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/CodeInspection/CodeAnnotations/NamespacesWithAnnotations/=Plix_002ECore_002EAnnotations/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
|
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
|
@ -0,0 +1,44 @@
|
||||||
|
<prism:PrismApplication
|
||||||
|
x:Class="PlixP.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:local="clr-namespace:PlixP"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:materialDesignDemo="clr-namespace:PlixP"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:showMeTheXaml="clr-namespace:ShowMeTheXAML;assembly=ShowMeTheXAML"
|
||||||
|
xmlns:smtxAe="clr-namespace:ShowMeTheXAML;assembly=ShowMeTheXAML"
|
||||||
|
xmlns:system="clr-namespace:System;assembly=System.Runtime">
|
||||||
|
<Application.Resources>
|
||||||
|
|
||||||
|
<ResourceDictionary>
|
||||||
|
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<hc:Theme Name="HandyTheme" Skin="Dark" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
<ResourceDictionary x:Key="DictionaryTest">
|
||||||
|
<system:String x:Key="str1a">String 1A</system:String>
|
||||||
|
<system:String x:Key="str1b">String 1B</system:String>
|
||||||
|
<system:String x:Key="str1c">String 1C</system:String>
|
||||||
|
<system:String x:Key="str1d">String 1A</system:String>
|
||||||
|
<system:String x:Key="str1e">String 1B</system:String>
|
||||||
|
<system:String x:Key="str1f">String 1C</system:String>
|
||||||
|
</ResourceDictionary>
|
||||||
|
|
||||||
|
<ResourceDictionary x:Key="Material">
|
||||||
|
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<materialDesign:BundledTheme
|
||||||
|
BaseTheme="Dark"
|
||||||
|
PrimaryColor="Yellow"
|
||||||
|
SecondaryColor="Orange" />
|
||||||
|
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
|
||||||
|
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
</ResourceDictionary>
|
||||||
|
<SolidColorBrush x:Key="PrimaryBrush" Color="#f1c40f" />
|
||||||
|
|
||||||
|
</ResourceDictionary>
|
||||||
|
</Application.Resources>
|
||||||
|
</prism:PrismApplication>
|
|
@ -0,0 +1,55 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using Prism.Ioc;
|
||||||
|
using PlixP.Views;
|
||||||
|
using System.Windows;
|
||||||
|
using AutoMapper;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using PlixP.Extentions;
|
||||||
|
using PlixP.Models;
|
||||||
|
using PlixP.Repositories;
|
||||||
|
using PlixP.Repositories.Contracts;
|
||||||
|
using PlixP.Services;
|
||||||
|
using PlixP.Services.Contracts;
|
||||||
|
|
||||||
|
namespace PlixP
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for App.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class App
|
||||||
|
{
|
||||||
|
protected override Window CreateShell()
|
||||||
|
{
|
||||||
|
var _catcherService = new CatcherService();
|
||||||
|
_catcherService.Delete<List<Movie>>(CatcherKeys.MovieList);
|
||||||
|
using (var _context = new PlixContext())
|
||||||
|
{
|
||||||
|
_context.Database.Migrate();
|
||||||
|
if (_context.Categories.Count() == 0)
|
||||||
|
{
|
||||||
|
_context.Categories.Add(new Category
|
||||||
|
{
|
||||||
|
Name = "Uncategorized"
|
||||||
|
});
|
||||||
|
_context.SaveChanges();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoMapperConfig.ConfigurationMapper();
|
||||||
|
App.Current.ConfigureExceptionHandling(AppDomain.CurrentDomain);
|
||||||
|
MovieServiceRealTime.Instance.StartReal();
|
||||||
|
return Container.Resolve<MainWindow>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
||||||
|
{
|
||||||
|
containerRegistry.RegisterForNavigation<MovieList>();
|
||||||
|
containerRegistry.Register<IServiceWrapper,ServiceWrapper>();
|
||||||
|
containerRegistry.Register<IRepositoryWrapper, RepositoryWrapper>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlixP.Extentions
|
||||||
|
{
|
||||||
|
public static class Assert
|
||||||
|
{
|
||||||
|
public static void NotNull<T>(T obj, string name, string message = null)
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
if (obj is null)
|
||||||
|
throw new ArgumentNullException($"{name} : {typeof(T)}", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void NotNull<T>(T? obj, string name, string message = null)
|
||||||
|
where T : struct
|
||||||
|
{
|
||||||
|
if (!obj.HasValue)
|
||||||
|
throw new ArgumentNullException($"{name} : {typeof(T)}", message);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void NotEmpty<T>(T obj, string name, string message = null, T defaultValue = null)
|
||||||
|
where T : class
|
||||||
|
{
|
||||||
|
if (obj == defaultValue
|
||||||
|
|| (obj is string str && string.IsNullOrWhiteSpace(str))
|
||||||
|
|| (obj is IEnumerable list && !list.Cast<object>().Any()))
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Argument is empty : " + message, $"{name} : {typeof(T)}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AutoMapper;
|
||||||
|
using PlixP.Models;
|
||||||
|
|
||||||
|
namespace PlixP.Extentions
|
||||||
|
{
|
||||||
|
public static class AutoMapperConfig
|
||||||
|
{
|
||||||
|
public static void ConfigurationMapper()
|
||||||
|
{
|
||||||
|
Mapper.Initialize(config => { config.AddCustomMapping(Assembly.GetEntryAssembly()); });
|
||||||
|
Mapper.Configuration.CompileMappings();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void AddCustomMapping(this IMapperConfigurationExpression expression, Assembly assemblies)
|
||||||
|
{
|
||||||
|
var allTypes = assemblies.ExportedTypes;
|
||||||
|
var list = allTypes
|
||||||
|
.Where(type => type.IsClass && !type.IsAbstract && type.GetInterfaces().Contains(typeof(IMapperConf)))
|
||||||
|
.Select(type => (IMapperConf)Activator.CreateInstance(type)).ToList();
|
||||||
|
expression.AddProfile(new CustomMappingProfile(list));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using MessageBox = HandyControl.Controls.MessageBox;
|
||||||
|
|
||||||
|
namespace PlixP.Extentions
|
||||||
|
{
|
||||||
|
public static class WpfExtensions
|
||||||
|
{
|
||||||
|
public static Brush FromHex(string hexColor)
|
||||||
|
{
|
||||||
|
return (SolidColorBrush)(new BrushConverter().ConvertFrom(hexColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ConfigureExceptionHandling(this Application application, AppDomain appDomain)
|
||||||
|
{
|
||||||
|
application.Dispatcher.UnhandledException += Dispatcher_UnhandledException;
|
||||||
|
application.DispatcherUnhandledException += Application_DispatcherUnhandledException;
|
||||||
|
appDomain.UnhandledException += AppDomain_UnhandledException;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AppDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||||
|
{
|
||||||
|
MessageBox.Show(e.ExceptionObject.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Handled == false)
|
||||||
|
{
|
||||||
|
MessageBox.Show(e.Exception.Message);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Dispatcher_UnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Handled == false)
|
||||||
|
{
|
||||||
|
MessageBox.Show(e.Exception.Message);
|
||||||
|
e.Handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||||
|
<PropertyChanged />
|
||||||
|
</Weavers>
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
|
||||||
|
<xs:element name="Weavers">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:all>
|
||||||
|
<xs:element name="PropertyChanged" minOccurs="0" maxOccurs="1">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="InjectOnPropertyNameChanged" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if the On_PropertyName_Changed feature is enabled.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="TriggerDependentProperties" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if the Dependent properties feature is enabled.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="EnableIsChangedProperty" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if the IsChanged property feature is enabled.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="EventInvokerNames" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="CheckForEquality" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="CheckForEqualityUsingBaseEquals" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if equality checks should use the Equals method resolved from the base class.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="UseStaticEqualsFromBase" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to control if equality checks should use the static Equals method resolved from the base class.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="SuppressWarnings" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to turn off build warnings from this weaver.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="SuppressOnPropertyNameChangedWarning" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>Used to turn off build warnings about mismatched On_PropertyName_Changed methods.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:all>
|
||||||
|
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
<xs:attribute name="GenerateXsd" type="xs:boolean">
|
||||||
|
<xs:annotation>
|
||||||
|
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
|
||||||
|
</xs:annotation>
|
||||||
|
</xs:attribute>
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:schema>
|
|
@ -0,0 +1,244 @@
|
||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PlixP.Models;
|
||||||
|
|
||||||
|
namespace PlixP.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PlixContext))]
|
||||||
|
[Migration("20201219204740_init")]
|
||||||
|
partial class init
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "5.0.1");
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Category", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRemoved")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Categories");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.CategoryMovie", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRemoved")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("MovieId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CategoryId");
|
||||||
|
|
||||||
|
b.HasIndex("MovieId");
|
||||||
|
|
||||||
|
b.ToTable("CategoryMovies");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Movie", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Actors")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Awards")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("BoxOffice")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Country")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("DVD")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Director")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("FileName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Genre")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRemoved")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsSeen")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Language")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Location")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Metascore")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Plot")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Poster")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Production")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Quality")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Rated")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Released")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Response")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Runtime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SyncStatus")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Type")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Website")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Writer")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Year")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("imdbID")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("imdbRating")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("imdbVotes")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Movies");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Rating", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRemoved")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("MovieId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Source")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("MovieId");
|
||||||
|
|
||||||
|
b.ToTable("Ratings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.CategoryMovie", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PlixP.Models.Category", "Category")
|
||||||
|
.WithMany("Movies")
|
||||||
|
.HasForeignKey("CategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("PlixP.Models.Movie", "Movie")
|
||||||
|
.WithMany("Category")
|
||||||
|
.HasForeignKey("MovieId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Category");
|
||||||
|
|
||||||
|
b.Navigation("Movie");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Rating", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PlixP.Models.Movie", "Movie")
|
||||||
|
.WithMany("Ratings")
|
||||||
|
.HasForeignKey("MovieId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Movie");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Category", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Movies");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Movie", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Category");
|
||||||
|
|
||||||
|
b.Navigation("Ratings");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace PlixP.Migrations
|
||||||
|
{
|
||||||
|
public partial class init : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Categories",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
Name = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
IsRemoved = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
CreationDate = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Categories", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Movies",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
FileName = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Location = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Quality = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Title = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Year = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Rated = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Released = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Runtime = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Genre = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Director = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Writer = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Actors = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Plot = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Language = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Country = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Awards = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Poster = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Metascore = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
imdbRating = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
imdbVotes = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
imdbID = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Type = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
DVD = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
BoxOffice = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Production = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Website = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Response = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
IsSeen = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
SyncStatus = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
IsRemoved = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
CreationDate = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Movies", x => x.Id);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "CategoryMovies",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
CategoryId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
MovieId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
IsRemoved = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
CreationDate = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_CategoryMovies", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_CategoryMovies_Categories_CategoryId",
|
||||||
|
column: x => x.CategoryId,
|
||||||
|
principalTable: "Categories",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_CategoryMovies_Movies_MovieId",
|
||||||
|
column: x => x.MovieId,
|
||||||
|
principalTable: "Movies",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Ratings",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||||
|
.Annotation("Sqlite:Autoincrement", true),
|
||||||
|
Source = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
Value = table.Column<string>(type: "TEXT", nullable: true),
|
||||||
|
MovieId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||||
|
IsRemoved = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||||
|
CreationDate = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Ratings", x => x.Id);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_Ratings_Movies_MovieId",
|
||||||
|
column: x => x.MovieId,
|
||||||
|
principalTable: "Movies",
|
||||||
|
principalColumn: "Id",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_CategoryMovies_CategoryId",
|
||||||
|
table: "CategoryMovies",
|
||||||
|
column: "CategoryId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_CategoryMovies_MovieId",
|
||||||
|
table: "CategoryMovies",
|
||||||
|
column: "MovieId");
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_Ratings_MovieId",
|
||||||
|
table: "Ratings",
|
||||||
|
column: "MovieId");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "CategoryMovies");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Ratings");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Categories");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Movies");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,242 @@
|
||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
using PlixP.Models;
|
||||||
|
|
||||||
|
namespace PlixP.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(PlixContext))]
|
||||||
|
partial class PlixContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "5.0.1");
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Category", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRemoved")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Categories");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.CategoryMovie", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("CategoryId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRemoved")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("MovieId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("CategoryId");
|
||||||
|
|
||||||
|
b.HasIndex("MovieId");
|
||||||
|
|
||||||
|
b.ToTable("CategoryMovies");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Movie", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Actors")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Awards")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("BoxOffice")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Country")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("DVD")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Director")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("FileName")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Genre")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRemoved")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<bool>("IsSeen")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Language")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Location")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Metascore")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Plot")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Poster")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Production")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Quality")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Rated")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Released")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Response")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Runtime")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<int>("SyncStatus")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Title")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Type")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Website")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Writer")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Year")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("imdbID")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("imdbRating")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("imdbVotes")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.ToTable("Movies");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Rating", b =>
|
||||||
|
{
|
||||||
|
b.Property<int>("Id")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreationDate")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<bool>("IsRemoved")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<int>("MovieId")
|
||||||
|
.HasColumnType("INTEGER");
|
||||||
|
|
||||||
|
b.Property<string>("Source")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.Property<string>("Value")
|
||||||
|
.HasColumnType("TEXT");
|
||||||
|
|
||||||
|
b.HasKey("Id");
|
||||||
|
|
||||||
|
b.HasIndex("MovieId");
|
||||||
|
|
||||||
|
b.ToTable("Ratings");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.CategoryMovie", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PlixP.Models.Category", "Category")
|
||||||
|
.WithMany("Movies")
|
||||||
|
.HasForeignKey("CategoryId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.HasOne("PlixP.Models.Movie", "Movie")
|
||||||
|
.WithMany("Category")
|
||||||
|
.HasForeignKey("MovieId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Category");
|
||||||
|
|
||||||
|
b.Navigation("Movie");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Rating", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("PlixP.Models.Movie", "Movie")
|
||||||
|
.WithMany("Ratings")
|
||||||
|
.HasForeignKey("MovieId")
|
||||||
|
.OnDelete(DeleteBehavior.Cascade)
|
||||||
|
.IsRequired();
|
||||||
|
|
||||||
|
b.Navigation("Movie");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Category", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Movies");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("PlixP.Models.Movie", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Category");
|
||||||
|
|
||||||
|
b.Navigation("Ratings");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Base Dto Class initial map config between entity and dto
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TDto">Type of Dto Class</typeparam>
|
||||||
|
/// <typeparam name="TEntity">Type of Entity Class</typeparam>
|
||||||
|
public abstract class BaseDto<TDto, TEntity> : IMapperConf
|
||||||
|
where TDto : class, new()
|
||||||
|
where TEntity : new()
|
||||||
|
{
|
||||||
|
|
||||||
|
public TEntity ToEntity()
|
||||||
|
{
|
||||||
|
return Mapper.Map<TEntity>(CastToDerivedClass(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TEntity ToEntity(TEntity entity)
|
||||||
|
{
|
||||||
|
return Mapper.Map(CastToDerivedClass(this), entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TDto FromEntity(TEntity model)
|
||||||
|
{
|
||||||
|
return Mapper.Map<TDto>(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TDto CastToDerivedClass(BaseDto<TDto, TEntity> baseInstance)
|
||||||
|
{
|
||||||
|
return Mapper.Map<TDto>(baseInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void MapperConfig(Profile profile)
|
||||||
|
{
|
||||||
|
var mappingExpression = profile.CreateMap<TDto, TEntity>();
|
||||||
|
|
||||||
|
var dtoType = typeof(TDto);
|
||||||
|
var entityType = typeof(TEntity);
|
||||||
|
//Ignore any property of source (like Post.Author) that dose not contains in destination
|
||||||
|
foreach (var property in entityType.GetProperties())
|
||||||
|
{
|
||||||
|
if (dtoType.GetProperty(property.Name) == null)
|
||||||
|
mappingExpression.ForMember(property.Name, opt => opt.Ignore());
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomMappings(mappingExpression.ReverseMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void CustomMappings(IMappingExpression<TEntity, TDto> mapping)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class Category : Entity
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public virtual ICollection<CategoryMovie> Movies { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class CategoryMovie : Entity
|
||||||
|
{
|
||||||
|
public int CategoryId { get; set; }
|
||||||
|
public int MovieId { get; set; }
|
||||||
|
public Category Category { get; set; }
|
||||||
|
public Movie Movie { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public bool IsEditable { get; set; } = false;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
public class CustomMappingProfile : Profile
|
||||||
|
{
|
||||||
|
public CustomMappingProfile(IEnumerable<IMapperConf> mapperConfs)
|
||||||
|
{
|
||||||
|
foreach (var mapperConf in mapperConfs)
|
||||||
|
mapperConf.MapperConfig(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class Entity
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public int Id { get; set; }
|
||||||
|
public bool IsRemoved { get; set; }
|
||||||
|
public DateTime CreationDate { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
public interface IMapperConf
|
||||||
|
{
|
||||||
|
void MapperConfig(Profile profile);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
public enum SyncStatus
|
||||||
|
{
|
||||||
|
Synced,
|
||||||
|
NotSynced
|
||||||
|
}
|
||||||
|
[Serializable]
|
||||||
|
public class Movie : Entity, ICloneable
|
||||||
|
{
|
||||||
|
public string FullName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Location != null && FileName != null)
|
||||||
|
return Path.Combine(Location, FileName);
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public string FileName { get; set; }
|
||||||
|
public string Location { get; set; }
|
||||||
|
public string Quality { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Year { get; set; }
|
||||||
|
|
||||||
|
public int IntYear
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int year;
|
||||||
|
if (string.IsNullOrEmpty(Year))
|
||||||
|
return 0;
|
||||||
|
if (int.TryParse(Year, out year))
|
||||||
|
return year;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Rated { get; set; }
|
||||||
|
public string Released { get; set; }
|
||||||
|
public string Runtime { get; set; }
|
||||||
|
public string Genre { get; set; }
|
||||||
|
public string Director { get; set; }
|
||||||
|
public string Writer { get; set; }
|
||||||
|
public string Actors { get; set; }
|
||||||
|
public string Plot { get; set; }
|
||||||
|
public string Language { get; set; }
|
||||||
|
public string Country { get; set; }
|
||||||
|
public string Awards { get; set; }
|
||||||
|
public string Poster { get; set; }
|
||||||
|
public string Metascore { get; set; }
|
||||||
|
public string imdbRating { get; set; }
|
||||||
|
public string imdbVotes { get; set; }
|
||||||
|
public string imdbID { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
|
public string DVD { get; set; }
|
||||||
|
public string BoxOffice { get; set; }
|
||||||
|
public string Production { get; set; }
|
||||||
|
public string Website { get; set; }
|
||||||
|
public string Response { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public bool IsDubbed
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (FullName != null && FullName.ToLower().Contains("dubbed"))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSeen { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public Color SeenStatusColor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (IsSeen)
|
||||||
|
return Color.LimeGreen;
|
||||||
|
else
|
||||||
|
return Color.OrangeRed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SyncStatus SyncStatus { get; set; }
|
||||||
|
public List<Rating> Ratings { get; set; }
|
||||||
|
public ObservableCollection<CategoryMovie> Category { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public List<string> CategoryNames { get; set; }
|
||||||
|
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
using (MemoryStream ms = new MemoryStream())
|
||||||
|
{
|
||||||
|
BinaryFormatter formatter = new BinaryFormatter();
|
||||||
|
formatter.Context = new StreamingContext(StreamingContextStates.Clone);
|
||||||
|
formatter.Serialize(ms, this);
|
||||||
|
ms.Position = 0;
|
||||||
|
return formatter.Deserialize(ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using AutoMapper;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
public class MovieDto : BaseDto<MovieDto,Movie>
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public bool IsRemoved { get; set; }
|
||||||
|
public DateTime CreationDate { get; set; }
|
||||||
|
public string FullName
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
public string FileName { get; set; }
|
||||||
|
public string Location { get; set; }
|
||||||
|
public string Quality { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Year { get; set; }
|
||||||
|
public string Rated { get; set; }
|
||||||
|
public string Released { get; set; }
|
||||||
|
public string Runtime { get; set; }
|
||||||
|
public string Genre { get; set; }
|
||||||
|
public string Director { get; set; }
|
||||||
|
public string Writer { get; set; }
|
||||||
|
public string Actors { get; set; }
|
||||||
|
public string Plot { get; set; }
|
||||||
|
public string Language { get; set; }
|
||||||
|
public string Country { get; set; }
|
||||||
|
public string Awards { get; set; }
|
||||||
|
public string Poster { get; set; }
|
||||||
|
public string Metascore { get; set; }
|
||||||
|
public string imdbRating { get; set; }
|
||||||
|
public string imdbVotes { get; set; }
|
||||||
|
public string imdbID { get; set; }
|
||||||
|
public string Type { get; set; }
|
||||||
|
public string DVD { get; set; }
|
||||||
|
public string BoxOffice { get; set; }
|
||||||
|
public string Production { get; set; }
|
||||||
|
public string Website { get; set; }
|
||||||
|
public string Response { get; set; }
|
||||||
|
public bool IsDubbed
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSeen { get; set; }
|
||||||
|
|
||||||
|
public Color SeenStatusColor
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SyncStatus SyncStatus { get; set; }
|
||||||
|
public List<Rating> Ratings { get; set; }
|
||||||
|
public ObservableCollection<CategoryMovie> Category { get; set; }
|
||||||
|
public List<string> CategoryNames { get; set; }
|
||||||
|
public override void CustomMappings(IMappingExpression<Movie, MovieDto> mapping)
|
||||||
|
{
|
||||||
|
base.CustomMappings(mapping);
|
||||||
|
mapping.ForMember(m => m.CategoryNames
|
||||||
|
, org => org.MapFrom(m => m.Category.Select(c => c.Category.Name).ToList()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
public class MovieListModel : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
public ObservableCollection<Movie> OriginalMovies { get; set; } = new ObservableCollection<Movie>();
|
||||||
|
public ObservableCollection<Category> OriginalCategories { get; set; } = new ObservableCollection<Category>();
|
||||||
|
public Dictionary<string, int> OriginalGenres { get; set; } = new Dictionary<string, int>();
|
||||||
|
|
||||||
|
public List<string> Genres
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return OriginalGenres.Select(g => string.Format("{0} | {1}", g.Key, g.Value.ToString())).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObservableCollection<Movie> UnPagedMovies { get; set; } = new ObservableCollection<Movie>();
|
||||||
|
public ObservableCollection<Movie> PageMovies { get; set; } = new ObservableCollection<Movie>();
|
||||||
|
|
||||||
|
public int MoviesCount { get; set; }
|
||||||
|
public bool AllChecked { get; set; }
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
|
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
public class PlixContext : DbContext
|
||||||
|
{
|
||||||
|
protected override void OnConfiguring(DbContextOptionsBuilder options)
|
||||||
|
=> options.UseSqlite("Data Source=plix.db");
|
||||||
|
public DbSet<Movie> Movies { get; set; }
|
||||||
|
public DbSet<Rating> Ratings { get; set; }
|
||||||
|
public DbSet<Category> Categories { get; set; }
|
||||||
|
public DbSet<CategoryMovie> CategoryMovies { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlixP.Models
|
||||||
|
{
|
||||||
|
[Serializable]
|
||||||
|
public class Rating : Entity
|
||||||
|
{
|
||||||
|
public string Source { get; set; }
|
||||||
|
public string Value { get; set; }
|
||||||
|
public int MovieId { get; set; }
|
||||||
|
public Movie Movie { get; set; }
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
|
@ -0,0 +1,46 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<TargetFramework>net5.0-windows</TargetFramework>
|
||||||
|
<UseWPF>true</UseWPF>
|
||||||
|
<AssemblyName>PlixP</AssemblyName>
|
||||||
|
<ApplicationIcon>PlixLogo.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Remove="Resources\PlixLogo.ico" />
|
||||||
|
<None Remove="Resources\SPLASH.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="AutoMapper" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Fody" Version="6.3.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="HandyControls" Version="3.0.0-rc.1" />
|
||||||
|
<PackageReference Include="MaterialDesignColors" Version="2.0.0-ci2312" />
|
||||||
|
<PackageReference Include="MaterialDesignThemes" Version="4.0.0-ci2312" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.1">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="5.0.1" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.1">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
|
<PackageReference Include="Prism.Unity" Version="8.0.0.1909" />
|
||||||
|
<PackageReference Include="Prism.Wpf" Version="8.0.0.1909" />
|
||||||
|
<PackageReference Include="PropertyChanged.Fody" Version="3.3.1" />
|
||||||
|
<PackageReference Include="RestSharp" Version="106.11.7" />
|
||||||
|
<PackageReference Include="ShowMeTheXAML" Version="2.0.0" />
|
||||||
|
<PackageReference Include="Xam.Plugins.Settings" Version="4.1.0-beta" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Resource Include="Resources\PlixLogo.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<SplashScreen Include="Resources\SPLASH.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,91 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
|
||||||
|
namespace PlixP.Renders
|
||||||
|
{
|
||||||
|
public class ImageCacher : Image
|
||||||
|
{
|
||||||
|
private string BaseRepos = string.Format("{0}\\PlixMovieCacheFolder\\", Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
|
||||||
|
private List<FileInfo> FileInfos;
|
||||||
|
private bool Sourced = false;
|
||||||
|
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ImageSourceProperty =
|
||||||
|
DependencyProperty.Register(nameof(ImageSource), typeof(string), typeof(ImageCacher),
|
||||||
|
new PropertyMetadata("", new PropertyChangedCallback(OnSetTextChanged)));
|
||||||
|
|
||||||
|
private static void OnSetTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
var imageC = d as ImageCacher;
|
||||||
|
var source = e.NewValue as string;
|
||||||
|
if (source != null)
|
||||||
|
{
|
||||||
|
var name = source.ToString().Split('/').Last();
|
||||||
|
var image = imageC.FileInfos.FirstOrDefault(f => f.Name == name);
|
||||||
|
if (image != null)
|
||||||
|
{
|
||||||
|
imageC.Sourced = true;
|
||||||
|
var src = new BitmapImage();
|
||||||
|
src.BeginInit();
|
||||||
|
src.UriSource = new Uri(Path.Combine(image.DirectoryName, image.Name), UriKind.Absolute);
|
||||||
|
src.CacheOption = BitmapCacheOption.OnLoad;
|
||||||
|
src.EndInit();
|
||||||
|
imageC.Source = src;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
App.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
using (WebClient webClient = new WebClient())
|
||||||
|
{
|
||||||
|
if (source != "N/A")
|
||||||
|
{
|
||||||
|
byte[] data = webClient.DownloadData(source.ToString());
|
||||||
|
File.WriteAllBytes(Path.Combine(imageC.BaseRepos, name), data);
|
||||||
|
imageC.Source = new BitmapImage(new Uri(Path.Combine(imageC.BaseRepos, name)));
|
||||||
|
imageC.Sourced = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
MessageBox.Show(exception.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string ImageSource
|
||||||
|
{
|
||||||
|
get { return (string)GetValue(ImageSourceProperty); }
|
||||||
|
set { SetValue(ImageSourceProperty, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageCacher()
|
||||||
|
{
|
||||||
|
var directoryInfo = new DirectoryInfo(BaseRepos);
|
||||||
|
if (!Directory.Exists(BaseRepos))
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory(BaseRepos);
|
||||||
|
}
|
||||||
|
FileInfos = directoryInfo.GetFiles().ToList();
|
||||||
|
if (FileInfos == null)
|
||||||
|
FileInfos = new List<FileInfo>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using PlixP.Extentions;
|
||||||
|
using PlixP.Models;
|
||||||
|
using PlixP.Repositories.Contracts;
|
||||||
|
|
||||||
|
namespace PlixP.Repositories
|
||||||
|
{
|
||||||
|
public class BaseRepository<T> : IBaseRepository<T>
|
||||||
|
where T : Entity
|
||||||
|
{
|
||||||
|
protected readonly PlixContext DbContext;
|
||||||
|
public DbSet<T> Entities { get; }
|
||||||
|
public virtual IQueryable<T> Table => Entities.Where(e => e.IsRemoved == false);
|
||||||
|
public virtual IQueryable<T> TableNoTracking => Entities.AsNoTracking().Where(e => e.IsRemoved == false);
|
||||||
|
|
||||||
|
public BaseRepository(PlixContext dbContext)
|
||||||
|
{
|
||||||
|
DbContext = dbContext;
|
||||||
|
Entities = DbContext.Set<T>(); // City => Cities
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Async Method
|
||||||
|
public virtual async Task<T> GetByIdAsync(CancellationToken cancellationToken, params object[] ids)
|
||||||
|
{
|
||||||
|
|
||||||
|
var entity = await Entities.FindAsync(ids, cancellationToken);
|
||||||
|
DbContext.Entry(entity).State = EntityState.Detached;
|
||||||
|
return entity;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task AddAsync(T entity, CancellationToken cancellationToken, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entity, nameof(entity));
|
||||||
|
entity.CreationDate = DateTime.Now;
|
||||||
|
await Entities.AddAsync(entity, cancellationToken).ConfigureAwait(false);
|
||||||
|
if (saveNow)
|
||||||
|
await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entities, nameof(entities));
|
||||||
|
await Entities.AddRangeAsync(entities, cancellationToken).ConfigureAwait(false);
|
||||||
|
if (saveNow)
|
||||||
|
await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task UpdateAsync(T entity, CancellationToken cancellationToken, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entity, nameof(entity));
|
||||||
|
DbContext.Entry(entity).State = EntityState.Detached;
|
||||||
|
await DbContext.SaveChangesAsync(cancellationToken);
|
||||||
|
//DbContext.Entry(entity).State = EntityState.Modified;
|
||||||
|
DbContext.Update(entity);
|
||||||
|
//DbContext.Entry(entity).CurrentValues.SetValues(entity);
|
||||||
|
if (saveNow)
|
||||||
|
await DbContext.SaveChangesAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task UpdateRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entities, nameof(entities));
|
||||||
|
Entities.UpdateRange(entities);
|
||||||
|
if (saveNow)
|
||||||
|
await DbContext.SaveChangesAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task DeleteAsync(T entity, CancellationToken cancellationToken, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entity, nameof(entity));
|
||||||
|
entity.IsRemoved = true;
|
||||||
|
Entities.Update(entity);
|
||||||
|
if (saveNow)
|
||||||
|
await DbContext.SaveChangesAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task HardDeleteAsync(T entity, CancellationToken cancellationToken, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entity, nameof(entity));
|
||||||
|
Entities.Remove(entity);
|
||||||
|
if (saveNow)
|
||||||
|
await DbContext.SaveChangesAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task DeleteRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entities, nameof(entities));
|
||||||
|
foreach (var apiEntity in entities)
|
||||||
|
{
|
||||||
|
apiEntity.IsRemoved = true;
|
||||||
|
Entities.Update(apiEntity);
|
||||||
|
}
|
||||||
|
if (saveNow)
|
||||||
|
await DbContext.SaveChangesAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Sync Methods
|
||||||
|
public virtual T GetById(params object[] ids)
|
||||||
|
{
|
||||||
|
var ent = Entities.Find(ids);
|
||||||
|
Detach(ent);
|
||||||
|
return ent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Add(T entity, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entity, nameof(entity));
|
||||||
|
Entities.Add(entity);
|
||||||
|
if (saveNow)
|
||||||
|
DbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void AddRange(IEnumerable<T> entities, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entities, nameof(entities));
|
||||||
|
Entities.AddRange(entities);
|
||||||
|
if (saveNow)
|
||||||
|
DbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Update(T entity, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entity, nameof(entity));
|
||||||
|
Detach(entity);
|
||||||
|
Entities.Update(entity);
|
||||||
|
DbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void UpdateRange(IEnumerable<T> entities, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entities, nameof(entities));
|
||||||
|
Entities.UpdateRange(entities);
|
||||||
|
if (saveNow)
|
||||||
|
DbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Delete(T entity, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entity, nameof(entity));
|
||||||
|
Entities.Remove(entity);
|
||||||
|
if (saveNow)
|
||||||
|
DbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void DeleteRange(IEnumerable<T> entities, bool saveNow = true)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entities, nameof(entities));
|
||||||
|
Entities.RemoveRange(entities);
|
||||||
|
if (saveNow)
|
||||||
|
DbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Attach & Detach
|
||||||
|
public virtual void Detach(T entity)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entity, nameof(entity));
|
||||||
|
var entry = DbContext.Entry(entity);
|
||||||
|
if (entry != null)
|
||||||
|
entry.State = EntityState.Detached;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Attach(T entity)
|
||||||
|
{
|
||||||
|
Assert.NotNull(entity, nameof(entity));
|
||||||
|
if (DbContext.Entry(entity).State == EntityState.Detached)
|
||||||
|
Entities.Attach(entity);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Explicit Loading
|
||||||
|
public virtual async Task LoadCollectionAsync<TProperty>(T entity, Expression<Func<T, IEnumerable<TProperty>>> collectionProperty, CancellationToken cancellationToken)
|
||||||
|
where TProperty : class
|
||||||
|
{
|
||||||
|
Attach(entity);
|
||||||
|
|
||||||
|
var collection = DbContext.Entry(entity).Collection(collectionProperty);
|
||||||
|
if (!collection.IsLoaded)
|
||||||
|
await collection.LoadAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void LoadCollection<TProperty>(T entity, Expression<Func<T, IEnumerable<TProperty>>> collectionProperty)
|
||||||
|
where TProperty : class
|
||||||
|
{
|
||||||
|
Attach(entity);
|
||||||
|
var collection = DbContext.Entry(entity).Collection(collectionProperty);
|
||||||
|
if (!collection.IsLoaded)
|
||||||
|
collection.Load();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual async Task LoadReferenceAsync<TProperty>(T entity, Expression<Func<T, TProperty>> referenceProperty, CancellationToken cancellationToken)
|
||||||
|
where TProperty : class
|
||||||
|
{
|
||||||
|
Attach(entity);
|
||||||
|
var reference = DbContext.Entry(entity).Reference(referenceProperty);
|
||||||
|
if (!reference.IsLoaded)
|
||||||
|
await reference.LoadAsync(cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void LoadReference<TProperty>(T entity, Expression<Func<T, TProperty>> referenceProperty)
|
||||||
|
where TProperty : class
|
||||||
|
{
|
||||||
|
Attach(entity);
|
||||||
|
var reference = DbContext.Entry(entity).Reference(referenceProperty);
|
||||||
|
if (!reference.IsLoaded)
|
||||||
|
reference.Load();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using PlixP.Models;
|
||||||
|
|
||||||
|
namespace PlixP.Repositories.Contracts
|
||||||
|
{
|
||||||
|
public interface IBaseRepository<T> where T : Entity
|
||||||
|
{
|
||||||
|
DbSet<T> Entities { get; }
|
||||||
|
IQueryable<T> Table { get; }
|
||||||
|
IQueryable<T> TableNoTracking { get; }
|
||||||
|
|
||||||
|
void Add(T entity, bool saveNow = true);
|
||||||
|
Task AddAsync(T entity, CancellationToken cancellationToken, bool saveNow = true);
|
||||||
|
void AddRange(IEnumerable<T> entities, bool saveNow = true);
|
||||||
|
Task AddRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken, bool saveNow = true);
|
||||||
|
void Attach(T entity);
|
||||||
|
void Delete(T entity, bool saveNow = true);
|
||||||
|
Task DeleteAsync(T entity, CancellationToken cancellationToken, bool saveNow = true);
|
||||||
|
Task HardDeleteAsync(T entity, CancellationToken cancellationToken, bool saveNow = true);
|
||||||
|
void DeleteRange(IEnumerable<T> entities, bool saveNow = true);
|
||||||
|
Task DeleteRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken, bool saveNow = true);
|
||||||
|
void Detach(T entity);
|
||||||
|
T GetById(params object[] ids);
|
||||||
|
Task<T> GetByIdAsync(CancellationToken cancellationToken, params object[] ids);
|
||||||
|
void LoadCollection<TProperty>(T entity, Expression<Func<T, IEnumerable<TProperty>>> collectionProperty) where TProperty : class;
|
||||||
|
Task LoadCollectionAsync<TProperty>(T entity, Expression<Func<T, IEnumerable<TProperty>>> collectionProperty, CancellationToken cancellationToken) where TProperty : class;
|
||||||
|
void LoadReference<TProperty>(T entity, Expression<Func<T, TProperty>> referenceProperty) where TProperty : class;
|
||||||
|
Task LoadReferenceAsync<TProperty>(T entity, Expression<Func<T, TProperty>> referenceProperty, CancellationToken cancellationToken) where TProperty : class;
|
||||||
|
void Update(T entity, bool saveNow = true);
|
||||||
|
Task UpdateAsync(T entity, CancellationToken cancellationToken, bool saveNow = true);
|
||||||
|
void UpdateRange(IEnumerable<T> entities, bool saveNow = true);
|
||||||
|
Task UpdateRangeAsync(IEnumerable<T> entities, CancellationToken cancellationToken, bool saveNow = true);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using PlixP.Models;
|
||||||
|
|
||||||
|
namespace PlixP.Repositories.Contracts
|
||||||
|
{
|
||||||
|
public interface IRepositoryWrapper
|
||||||
|
{
|
||||||
|
IBaseRepository<T> SetRepository<T>() where T : Entity;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using PlixP.Models;
|
||||||
|
using PlixP.Repositories.Contracts;
|
||||||
|
|
||||||
|
namespace PlixP.Repositories
|
||||||
|
{
|
||||||
|
public class RepositoryWrapper : IRepositoryWrapper
|
||||||
|
{
|
||||||
|
private readonly PlixContext _context;
|
||||||
|
public RepositoryWrapper(PlixContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
public IBaseRepository<T> SetRepository<T>() where T : Entity
|
||||||
|
{
|
||||||
|
IBaseRepository<T> repository = new BaseRepository<T>(_context);
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 122 KiB |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
|
@ -0,0 +1,49 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Plugin.Settings;
|
||||||
|
|
||||||
|
namespace PlixP.Services
|
||||||
|
{
|
||||||
|
public static class CatcherKeys
|
||||||
|
{
|
||||||
|
public static string MovieList { get; } = "Movies";
|
||||||
|
}
|
||||||
|
public class CatcherService
|
||||||
|
{
|
||||||
|
public void Set(object item, string key = null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(key))
|
||||||
|
{
|
||||||
|
key = item.GetType().Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
var json = JsonConvert.SerializeObject(item,Formatting.None, new JsonSerializerSettings()
|
||||||
|
{
|
||||||
|
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
|
||||||
|
});
|
||||||
|
Plugin.Settings.CrossSettings.Current.AddOrUpdateValue(key, json);
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Get<T>(string key = null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(key))
|
||||||
|
key = typeof(T).Name;
|
||||||
|
var json = CrossSettings.Current.GetValueOrDefault(key, string.Empty);
|
||||||
|
if (string.IsNullOrEmpty(json))
|
||||||
|
return Activator.CreateInstance<T>();
|
||||||
|
return JsonConvert.DeserializeObject<T>(json);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Delete<T>(string key = null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(key))
|
||||||
|
key = typeof(T).Name;
|
||||||
|
CrossSettings.Current.Remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace PlixP.Services.Contracts
|
||||||
|
{
|
||||||
|
public interface IServiceWrapper
|
||||||
|
{
|
||||||
|
LocalServices LocalServices { get; }
|
||||||
|
MovieServices MovieServices { get; }
|
||||||
|
CatcherService CatcherService { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,216 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace PlixP.Services
|
||||||
|
{
|
||||||
|
|
||||||
|
public class LocalServices
|
||||||
|
{
|
||||||
|
private string[] extentions = { ".mp4", ".mkv", ".avi" };
|
||||||
|
private List<DirectoryInfo> _baseDires = new List<DirectoryInfo>();
|
||||||
|
private List<string> paths = new List<string>();
|
||||||
|
public LocalServices()
|
||||||
|
{
|
||||||
|
|
||||||
|
var pathsJson = Plugin.Settings.CrossSettings.Current.GetValueOrDefault("Paths", string.Empty);
|
||||||
|
paths = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(pathsJson);
|
||||||
|
if (paths == null)
|
||||||
|
paths = new List<string>();
|
||||||
|
if (paths.Count > 0)
|
||||||
|
paths.ForEach(p => _baseDires.Add(new DirectoryInfo(p)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetFolder()
|
||||||
|
{
|
||||||
|
RenameAllFile(GetMovieFiles());
|
||||||
|
CreateUnFolders(GetMovieFiles());
|
||||||
|
RenameAllFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetFolderNameByMovieFileName(string movieN)
|
||||||
|
{
|
||||||
|
string movieName = string.Empty;
|
||||||
|
bool yeared = false;
|
||||||
|
bool qualited = false;
|
||||||
|
movieN = movieN.Replace('-', '.');
|
||||||
|
movieN = movieN.Replace('_', '.');
|
||||||
|
foreach (var str in movieN.Split('.'))
|
||||||
|
{
|
||||||
|
int year = 0;
|
||||||
|
if (int.TryParse(str, out year) && (year >= 1920 && year <= 2142))
|
||||||
|
{
|
||||||
|
movieName += "(" + year + ")" + " ";
|
||||||
|
yeared = true;
|
||||||
|
}
|
||||||
|
else if (str.Contains("720") || str.Contains("1080") || str.ToLower().Contains("dvdsrc") || str.ToLower().Contains("hdrip") || str.ToLower().Contains("dvdrip"))
|
||||||
|
{
|
||||||
|
movieName += "[" + str + "]";
|
||||||
|
qualited = true;
|
||||||
|
}
|
||||||
|
else if (!yeared && !qualited)
|
||||||
|
{
|
||||||
|
movieName += str + " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return movieName;
|
||||||
|
}
|
||||||
|
private void RenameAllFolder()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (paths.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var path in paths)
|
||||||
|
{
|
||||||
|
DirectoryInfo directoryInfo = new DirectoryInfo(path);
|
||||||
|
string baseDire = directoryInfo.Name;
|
||||||
|
var dires = GetDirectoryInfos(directoryInfo);
|
||||||
|
foreach (var dir in dires)
|
||||||
|
{
|
||||||
|
string movieN = string.Empty;
|
||||||
|
string movieName = string.Empty;
|
||||||
|
foreach (var fileInfo in dir.GetFiles())
|
||||||
|
{
|
||||||
|
if (fileInfo.Name.Contains(extentions[0]) || fileInfo.Name.Contains(extentions[1]) || fileInfo.Name.Contains(extentions[2]))
|
||||||
|
movieN = fileInfo.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(movieN))
|
||||||
|
{
|
||||||
|
movieName = GetFolderNameByMovieFileName(movieN);
|
||||||
|
DirectoryInfo di = new DirectoryInfo(string.Concat(dir.Parent, "\\", movieName));
|
||||||
|
if (!di.Exists)
|
||||||
|
Directory.Move(dir.FullName, string.Concat(dir.Parent, "\\", movieName));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageBox.Show(e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<FileInfo> GetMovieFiles()
|
||||||
|
{
|
||||||
|
if (paths.Count > 0)
|
||||||
|
{
|
||||||
|
var allFiles = new List<FileInfo>();
|
||||||
|
foreach (var path in paths)
|
||||||
|
{
|
||||||
|
DirectoryInfo dir = new DirectoryInfo(path);
|
||||||
|
string baseDire = dir.Name;
|
||||||
|
var dires = GetDirectoryInfos(dir);
|
||||||
|
List<FileInfo> files = new List<FileInfo>();
|
||||||
|
foreach (var directoryInfo in dires)
|
||||||
|
{
|
||||||
|
files.AddRange(directoryInfo.GetFiles());
|
||||||
|
}
|
||||||
|
allFiles.AddRange(files);
|
||||||
|
}
|
||||||
|
return allFiles.Where(f => extentions.Contains(f.Extension)).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return new List<FileInfo>();
|
||||||
|
}
|
||||||
|
public void RenameAllFile(List<FileInfo> fileInfos)
|
||||||
|
{
|
||||||
|
fileInfos.ForEach(m =>
|
||||||
|
{
|
||||||
|
string newName = "";
|
||||||
|
foreach (var str in m.DirectoryName.Split("\\"))
|
||||||
|
{
|
||||||
|
newName += str + "\\";
|
||||||
|
}
|
||||||
|
var name = m.Name.Replace('_', '.');
|
||||||
|
name = name.Replace(' ', '.');
|
||||||
|
newName += name;
|
||||||
|
File.Move(m.FullName, newName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
public void CreateUnFolders(List<FileInfo> movies)
|
||||||
|
{
|
||||||
|
foreach (var baseDire in _baseDires)
|
||||||
|
{
|
||||||
|
|
||||||
|
movies.Where(m => m.DirectoryName.Split('\\').Last() == baseDire.Name).ToList().ForEach(m =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string movieName = "";
|
||||||
|
bool yeared = false;
|
||||||
|
bool qualited = false;
|
||||||
|
foreach (var str in m.Name.Split('.'))
|
||||||
|
{
|
||||||
|
int year = 0;
|
||||||
|
if (int.TryParse(str, out year) && (year >= 1920 && year <= 2142))
|
||||||
|
{
|
||||||
|
movieName += "(" + year + ")" + " ";
|
||||||
|
yeared = true;
|
||||||
|
}
|
||||||
|
else if (str.Contains("720") || str.Contains("1080") || str.ToLower().Contains("dvdsrc") || str.ToLower().Contains("hdrip") || str.ToLower().Contains("dvdrip"))
|
||||||
|
{
|
||||||
|
movieName += "[" + str + "]";
|
||||||
|
qualited = true;
|
||||||
|
}
|
||||||
|
else if (!yeared && !qualited && !extentions.Contains(str))
|
||||||
|
{
|
||||||
|
movieName += str + " ";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var newDire = Path.Combine(m.DirectoryName, movieName).Trim();
|
||||||
|
Directory.CreateDirectory(newDire);
|
||||||
|
var orgFile = m.FullName;
|
||||||
|
var desFile = Path.Combine(newDire, m.Name);
|
||||||
|
File.Move(orgFile, desFile);
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
MessageBox.Show(e.Message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public List<DirectoryInfo> GetDirectoryInfos(DirectoryInfo baseDirectoryInfo)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<DirectoryInfo> directoryInfos = new List<DirectoryInfo>();
|
||||||
|
var dires = baseDirectoryInfo.GetDirectories();
|
||||||
|
if (dires.Length > 0)
|
||||||
|
{
|
||||||
|
foreach (var directory in dires)
|
||||||
|
{
|
||||||
|
directoryInfos.AddRange(GetDirectoryInfos(directory));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
directoryInfos.Add(baseDirectoryInfo);
|
||||||
|
return directoryInfos;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e);
|
||||||
|
return new List<DirectoryInfo>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void RenameFile(FileInfo oldFile, FileInfo newFile)
|
||||||
|
{
|
||||||
|
File.Move(oldFile.FullName, newFile.FullName);
|
||||||
|
}
|
||||||
|
public void RenameDirection(DirectoryInfo oldDirectory, DirectoryInfo newDirectory)
|
||||||
|
{
|
||||||
|
Directory.Move(oldDirectory.FullName, newDirectory.FullName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,389 @@
|
||||||
|
using RestSharp;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using AutoMapper.QueryableExtensions;
|
||||||
|
using HandyControl.Controls;
|
||||||
|
using MaterialDesignThemes.Wpf;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using PlixP.Models;
|
||||||
|
using PlixP.Repositories;
|
||||||
|
using PlixP.ViewModels;
|
||||||
|
using PlixP.Views.Dialogs;
|
||||||
|
using MessageBox = HandyControl.Controls.MessageBox;
|
||||||
|
using Timer = System.Timers.Timer;
|
||||||
|
|
||||||
|
namespace PlixP.Services
|
||||||
|
{
|
||||||
|
public class MovieServiceRealTime
|
||||||
|
{
|
||||||
|
private static MovieServiceRealTime _instance;
|
||||||
|
public static MovieServiceRealTime Instance
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_instance == null)
|
||||||
|
_instance = new MovieServiceRealTime();
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LocalServices _localServices;
|
||||||
|
private MovieServices _movieServices;
|
||||||
|
private bool IsWorking = false;
|
||||||
|
private List<FileInfo> _currentFiles = new List<FileInfo>();
|
||||||
|
private Timer timer;
|
||||||
|
public List<Movie> CurreMovies
|
||||||
|
{
|
||||||
|
get { return _movieServices.GetMovies().Result; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public MovieServiceRealTime()
|
||||||
|
{
|
||||||
|
timer = new Timer(6000);
|
||||||
|
_localServices = new LocalServices();
|
||||||
|
_movieServices = new MovieServices();
|
||||||
|
timer.Elapsed += Timer_Elapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartReal() => timer.Start();
|
||||||
|
|
||||||
|
private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
CheckAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task CheckAll()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (IsWorking)
|
||||||
|
return;
|
||||||
|
IsWorking = true;
|
||||||
|
_localServices.ResetFolder();
|
||||||
|
var movieFolders = _localServices.GetMovieFiles();
|
||||||
|
foreach (var f in movieFolders)
|
||||||
|
{
|
||||||
|
if (!CurreMovies.Any(m => m.Location == f.DirectoryName))
|
||||||
|
{
|
||||||
|
await _movieServices.AddNewMovieToDb(f);
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
Growl.SuccessGlobal("Movie Added : " + f.Name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var m in CurreMovies.Where(m => m.SyncStatus == SyncStatus.NotSynced))
|
||||||
|
{
|
||||||
|
var creationDate = m.CreationDate;
|
||||||
|
var movie = await _movieServices.GetMovieAsync(m.Title);
|
||||||
|
if (movie != null)
|
||||||
|
{
|
||||||
|
movie.CreationDate = creationDate;
|
||||||
|
movie.Id = m.Id;
|
||||||
|
movie.Location = m.Location;
|
||||||
|
movie.FileName = m.FileName;
|
||||||
|
movie.SyncStatus = SyncStatus.Synced;
|
||||||
|
await _movieServices.EditMovie(movie, SyncStatus.Synced);
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
Growl.WarningGlobal("Movie Synced : " + movie.FullName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
IsWorking = false;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageBox.Show(e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public class MovieServices
|
||||||
|
{
|
||||||
|
private readonly RepositoryWrapper _repositoryWrapper;
|
||||||
|
private readonly LocalServices _localServices;
|
||||||
|
private readonly CatcherService _catcherService;
|
||||||
|
|
||||||
|
public MovieServices()
|
||||||
|
{
|
||||||
|
_repositoryWrapper = new RepositoryWrapper(new PlixContext());
|
||||||
|
_localServices = new LocalServices();
|
||||||
|
_catcherService = new CatcherService();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async Task<List<Movie>> GetMovies()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<Movie> Movies = new List<Movie>();
|
||||||
|
Movies = _catcherService.Get<List<Movie>>(CatcherKeys.MovieList);
|
||||||
|
if (Movies != null)
|
||||||
|
if (Movies.Count != 0)
|
||||||
|
return Movies;
|
||||||
|
var dtos = _repositoryWrapper.SetRepository<Movie>()
|
||||||
|
.TableNoTracking
|
||||||
|
.ProjectTo<MovieDto>()
|
||||||
|
.ToList();
|
||||||
|
dtos.ForEach(m => Movies.Add(m.ToEntity()));
|
||||||
|
foreach (var movie in Movies)
|
||||||
|
{
|
||||||
|
foreach (var categoryMovie in movie.Category)
|
||||||
|
{
|
||||||
|
categoryMovie.Category = await _repositoryWrapper.SetRepository<Category>()
|
||||||
|
.GetByIdAsync(CancellationToken.None, categoryMovie.CategoryId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_catcherService.Set(Movies, CatcherKeys.MovieList);
|
||||||
|
return Movies;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Movie> AddNewMovieToDb(FileInfo f)
|
||||||
|
{
|
||||||
|
var cMovie = new Movie();
|
||||||
|
var mName = f.Directory.Name.Split("(")[0];
|
||||||
|
cMovie = await GetMovieAsync(mName);
|
||||||
|
string q = " ";
|
||||||
|
if (f.Name.Contains("720"))
|
||||||
|
q = "720P";
|
||||||
|
else if (f.Name.Contains("1080"))
|
||||||
|
q = "1080P";
|
||||||
|
if (cMovie != null)
|
||||||
|
{
|
||||||
|
cMovie.FileName = f.Name;
|
||||||
|
cMovie.Location = f.DirectoryName;
|
||||||
|
cMovie.Quality = q;
|
||||||
|
cMovie.SyncStatus = SyncStatus.Synced;
|
||||||
|
cMovie.CreationDate = DateTime.Now;
|
||||||
|
await _repositoryWrapper.SetRepository<Movie>().AddAsync(cMovie, CancellationToken.None);
|
||||||
|
await _repositoryWrapper.SetRepository<CategoryMovie>().AddAsync(new CategoryMovie
|
||||||
|
{
|
||||||
|
MovieId = cMovie.Id,
|
||||||
|
CategoryId = 1
|
||||||
|
}, CancellationToken.None);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cMovie = new Movie();
|
||||||
|
cMovie.Location = f.DirectoryName;
|
||||||
|
cMovie.FileName = f.Name;
|
||||||
|
cMovie.Quality = q;
|
||||||
|
cMovie.Title = mName;
|
||||||
|
cMovie.CreationDate = DateTime.Now;
|
||||||
|
cMovie.SyncStatus = SyncStatus.NotSynced;
|
||||||
|
|
||||||
|
|
||||||
|
await _repositoryWrapper.SetRepository<Movie>().AddAsync(cMovie, CancellationToken.None);
|
||||||
|
await _repositoryWrapper.SetRepository<CategoryMovie>().AddAsync(new CategoryMovie
|
||||||
|
{
|
||||||
|
MovieId = cMovie.Id,
|
||||||
|
CategoryId = 1
|
||||||
|
}, CancellationToken.None);
|
||||||
|
}
|
||||||
|
_catcherService.Delete<List<Movie>>(CatcherKeys.MovieList);
|
||||||
|
return cMovie;
|
||||||
|
}
|
||||||
|
public async Task<Movie> GetMovieAsync(string movieName)
|
||||||
|
{
|
||||||
|
RestClient client = new RestClient();
|
||||||
|
RestRequest request = new RestRequest("http://omdbapi.com", Method.GET);
|
||||||
|
request.AddQueryParameter("t", movieName);
|
||||||
|
request.AddQueryParameter("apikey", "a915dcc9");
|
||||||
|
var res = await client.ExecuteGetAsync<Movie>(request);
|
||||||
|
if (res.StatusCode == HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
if (res.Data.Response != "False")
|
||||||
|
return res.Data;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
Growl.ErrorGlobal($"Cant Sync Movie {movieName} , Please Edit Movie Detail");
|
||||||
|
});*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
Growl.ErrorGlobal($"Cant Sync Movie {movieName} , Please Edit Movie Detail");
|
||||||
|
});*/
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public async Task EditMovie(Movie newMovie, SyncStatus syncStatus = SyncStatus.NotSynced)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var oldMovie = await _repositoryWrapper.SetRepository<Movie>()
|
||||||
|
.GetByIdAsync(CancellationToken.None, newMovie.Id);
|
||||||
|
string newMovieFileName = string.Empty;
|
||||||
|
|
||||||
|
foreach (var str in newMovie.Title.Split(" "))
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(str))
|
||||||
|
continue;
|
||||||
|
newMovieFileName += str + ".";
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrWhiteSpace(newMovie.Year))
|
||||||
|
newMovieFileName += newMovie.Year + ".";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var str in oldMovie.FileName.Split("."))
|
||||||
|
{
|
||||||
|
|
||||||
|
int year = 0;
|
||||||
|
if (int.TryParse(str, out year) && (year >= 1920 && year <= 2142))
|
||||||
|
{
|
||||||
|
newMovieFileName += year + ".";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrWhiteSpace(newMovie.Quality))
|
||||||
|
newMovieFileName += newMovie.Quality + ".";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool qulited = false;
|
||||||
|
foreach (var str in oldMovie.FileName.Split("."))
|
||||||
|
{
|
||||||
|
if (str.Contains("720") || str.Contains("1080") || str.ToLower().Contains("dvdsrc") || str.ToLower().Contains("hdrip") || str.ToLower().Contains("dvdrip"))
|
||||||
|
{
|
||||||
|
newMovieFileName += str + ".";
|
||||||
|
newMovie.Quality = str;
|
||||||
|
qulited = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!qulited)
|
||||||
|
{
|
||||||
|
newMovieFileName += "720" + ".";
|
||||||
|
newMovie.Quality = "720";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
newMovieFileName += oldMovie.FileName.Split(".").Last();
|
||||||
|
newMovie.FileName = newMovieFileName;
|
||||||
|
newMovie.FileName = newMovie.FileName.Replace(":", "");
|
||||||
|
newMovie.FileName = newMovie.FileName.Replace(@"\", "");
|
||||||
|
newMovie.FileName = newMovie.FileName.Replace("?", "");
|
||||||
|
newMovie.FileName = newMovie.FileName.Replace("*", "");
|
||||||
|
newMovie.FileName = newMovie.FileName.Replace("/", "");
|
||||||
|
newMovie.FileName = newMovie.FileName.Replace("<", "");
|
||||||
|
newMovie.FileName = newMovie.FileName.Replace(">", "");
|
||||||
|
newMovie.FileName = newMovie.FileName.Replace("|", "");
|
||||||
|
|
||||||
|
var folderName = _localServices.GetFolderNameByMovieFileName(newMovie.FileName);
|
||||||
|
var location = Path.Combine(newMovie.Location.Split("\\").Take(newMovie.Location.Split("\\").Length - 1)
|
||||||
|
.ToArray());
|
||||||
|
newMovie.Location = $"{Path.Combine(location, folderName)}";
|
||||||
|
newMovie.SyncStatus = syncStatus;
|
||||||
|
newMovie.Category = null;
|
||||||
|
await _repositoryWrapper.SetRepository<Movie>().UpdateAsync(newMovie, CancellationToken.None);
|
||||||
|
if (oldMovie.Location != newMovie.Location)
|
||||||
|
_localServices.RenameDirection(new DirectoryInfo(oldMovie.Location), new DirectoryInfo(newMovie.Location));
|
||||||
|
oldMovie.Location = Path.Combine(location, folderName);
|
||||||
|
_localServices.RenameFile(new FileInfo(oldMovie.FullName), new FileInfo(newMovie.FullName));
|
||||||
|
_catcherService.Delete<List<Movie>>(CatcherKeys.MovieList);
|
||||||
|
MessageBox.Show($"Movie {newMovie.Title} Was Edited !");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageBox.Show(e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public async Task<Dictionary<string, int>> GetGenres()
|
||||||
|
{
|
||||||
|
List<Movie> Movies = await GetMovies();
|
||||||
|
var originalGenres = Movies.Select(m => m.Genre).ToList();
|
||||||
|
Dictionary<string, int> genres = new Dictionary<string, int>();
|
||||||
|
foreach (var originalGenre in originalGenres)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(originalGenre))
|
||||||
|
continue;
|
||||||
|
var split = originalGenre.Split(',');
|
||||||
|
foreach (var str in split)
|
||||||
|
{
|
||||||
|
var trim = str.Trim();
|
||||||
|
if (genres.ContainsKey(trim))
|
||||||
|
genres[trim]++;
|
||||||
|
else
|
||||||
|
genres.Add(trim, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return genres;
|
||||||
|
}
|
||||||
|
public async Task<List<GenreItemModel>> GetGenresModel()
|
||||||
|
{
|
||||||
|
List<Movie> Movies = await GetMovies();
|
||||||
|
var originalGenres = Movies.Select(m => m.Genre).ToList();
|
||||||
|
List<GenreItemModel> genres = new List<GenreItemModel>();
|
||||||
|
foreach (var originalGenre in originalGenres)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(originalGenre))
|
||||||
|
continue;
|
||||||
|
var split = originalGenre.Split(',');
|
||||||
|
foreach (var str in split)
|
||||||
|
{
|
||||||
|
var trim = str.Trim();
|
||||||
|
var genre = genres.FirstOrDefault(g=>g.Name==trim);
|
||||||
|
if (genre!=null)
|
||||||
|
genre.MovieCount++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var item = new GenreItemModel
|
||||||
|
{
|
||||||
|
MovieCount = 1,
|
||||||
|
Name = trim
|
||||||
|
};
|
||||||
|
foreach (var movie in Movies.Where(m=>m.Genre.Contains(trim)))
|
||||||
|
{
|
||||||
|
var poster = movie.Poster;
|
||||||
|
if (!genres.Any(g => g.Image == poster))
|
||||||
|
item.Image = poster;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.Image == null)
|
||||||
|
item.Image = Movies.FirstOrDefault(m => m.Genre.Contains(trim))?.Poster;
|
||||||
|
genres = genres.OrderByDescending(g => g.MovieCount).ToList();
|
||||||
|
genres.Add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
return genres;
|
||||||
|
}
|
||||||
|
public async Task<List<Movie>> SelectByGenre(string genre)
|
||||||
|
{
|
||||||
|
return (await GetMovies()).Where(m => m.Genre.Contains(genre))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
public async Task DeleteMovie(Movie movie)
|
||||||
|
{
|
||||||
|
movie.Category = null;
|
||||||
|
await _repositoryWrapper.SetRepository<Movie>()
|
||||||
|
.DeleteAsync(movie, CancellationToken.None);
|
||||||
|
_catcherService.Delete<List<Movie>>(CatcherKeys.MovieList);
|
||||||
|
MovieServiceRealTime.Instance.CurreMovies.RemoveAll(m => m.Id == movie.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using PlixP.Services.Contracts;
|
||||||
|
|
||||||
|
namespace PlixP.Services
|
||||||
|
{
|
||||||
|
public class ServiceWrapper : IServiceWrapper
|
||||||
|
{
|
||||||
|
private LocalServices _localServices;
|
||||||
|
|
||||||
|
public LocalServices LocalServices
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_localServices == null)
|
||||||
|
_localServices = new LocalServices();
|
||||||
|
return _localServices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private MovieServices _movieServices;
|
||||||
|
|
||||||
|
public MovieServices MovieServices
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_movieServices == null)
|
||||||
|
_movieServices = new MovieServices();
|
||||||
|
return _movieServices;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CatcherService _catcherService;
|
||||||
|
|
||||||
|
public CatcherService CatcherService
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_catcherService == null)
|
||||||
|
_catcherService = new CatcherService();
|
||||||
|
return _catcherService;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using Prism.Commands;
|
||||||
|
using Prism.Mvvm;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace PlixP.ViewModels
|
||||||
|
{
|
||||||
|
public class AddCategoryDialogViewModel : BindableBase
|
||||||
|
{
|
||||||
|
public AddCategoryDialogViewModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
using Prism.Commands;
|
||||||
|
using Prism.Mvvm;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using PlixP.Repositories.Contracts;
|
||||||
|
using PlixP.Services.Contracts;
|
||||||
|
|
||||||
|
namespace PlixP.ViewModels
|
||||||
|
{
|
||||||
|
public class GenreItemModel
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Image { get; set; }
|
||||||
|
public int MovieCount { get; set; }
|
||||||
|
}
|
||||||
|
public class GenresDialogViewModel : BindableBase
|
||||||
|
{
|
||||||
|
private readonly IServiceWrapper _serviceWrapper;
|
||||||
|
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||||
|
public event EventHandler<string> GenreSelected;
|
||||||
|
public ICommand GenreSelectCommand { get; set; }
|
||||||
|
public ObservableCollection<GenreItemModel> Genres { get; set; } = new ObservableCollection<GenreItemModel>();
|
||||||
|
public GenresDialogViewModel(IServiceWrapper serviceWrapper,IRepositoryWrapper repositoryWrapper)
|
||||||
|
{
|
||||||
|
_serviceWrapper = serviceWrapper;
|
||||||
|
_repositoryWrapper = repositoryWrapper;
|
||||||
|
GenreSelectCommand = new DelegateCommand<GenreItemModel>(model =>
|
||||||
|
{
|
||||||
|
GenreSelected?.Invoke(model, model.Name);
|
||||||
|
});
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Initialize()
|
||||||
|
{
|
||||||
|
|
||||||
|
(await _serviceWrapper.MovieServices.GetGenresModel()).ForEach(g=>Genres.Add(g));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using PlixP.Services.Contracts;
|
||||||
|
using PlixP.Views;
|
||||||
|
using Prism.Mvvm;
|
||||||
|
using Prism.Regions;
|
||||||
|
|
||||||
|
namespace PlixP.ViewModels
|
||||||
|
{
|
||||||
|
public class MainWindowViewModel : BindableBase
|
||||||
|
{
|
||||||
|
private string _title = "Prism Application";
|
||||||
|
public string Title
|
||||||
|
{
|
||||||
|
get { return _title; }
|
||||||
|
set { SetProperty(ref _title, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int _count;
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get { return _count; }
|
||||||
|
set { SetProperty(ref _count, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _background;
|
||||||
|
|
||||||
|
public string Background
|
||||||
|
{
|
||||||
|
get { return _background; }
|
||||||
|
set { SetProperty(ref _background, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public MainWindowViewModel(IServiceWrapper serviceWrapper , IRegionManager regionManager)
|
||||||
|
{
|
||||||
|
var bg = Plugin.Settings.CrossSettings.Current.GetValueOrDefault("Background", string.Empty);
|
||||||
|
if (string.IsNullOrEmpty(bg))
|
||||||
|
Background = "https://www.jakpost.travel/wimages/large/166-1664172_lord-of-the-rings-background.jpg";
|
||||||
|
else
|
||||||
|
Background = bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
using Prism.Commands;
|
||||||
|
using Prism.Mvvm;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Timers;
|
||||||
|
using System.Windows;
|
||||||
|
using MaterialDesignThemes.Wpf;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using Microsoft.Xaml.Behaviors.Core;
|
||||||
|
using PlixP.Models;
|
||||||
|
using PlixP.Repositories.Contracts;
|
||||||
|
using PlixP.Services.Contracts;
|
||||||
|
using PlixP.Views;
|
||||||
|
using PlixP.Views.Dialogs;
|
||||||
|
|
||||||
|
namespace PlixP.ViewModels
|
||||||
|
{
|
||||||
|
public class MasterDetailViewModel : BindableBase
|
||||||
|
{
|
||||||
|
public ObservableCollection<string> Paths { get; set; } = new ObservableCollection<string>();
|
||||||
|
public DelegateCommand<string> PathCommand { get; set; }
|
||||||
|
public DelegateCommand<string> AddCategoryCommand { get; set; }
|
||||||
|
public DelegateCommand ResetFolderCommand { get; set; }
|
||||||
|
public DelegateCommand ChangeBackGroundCommand { get; set; }
|
||||||
|
public DelegateCommand<string> RemovePathCommand { get; set; }
|
||||||
|
public DelegateCommand ResetDbCommand { get; set; }
|
||||||
|
public MasterDetailViewModel(IRepositoryWrapper repositoryWrapper, IServiceWrapper serviceWrapper)
|
||||||
|
{
|
||||||
|
var pathsJson = Plugin.Settings.CrossSettings.Current.GetValueOrDefault("Paths", string.Empty);
|
||||||
|
if (!string.IsNullOrEmpty(pathsJson))
|
||||||
|
{
|
||||||
|
var paths = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(pathsJson);
|
||||||
|
if (paths != null)
|
||||||
|
paths.ForEach(p => Paths.Add(p));
|
||||||
|
}
|
||||||
|
PathCommand = new DelegateCommand<string>((str) =>
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(str))
|
||||||
|
{
|
||||||
|
Paths.Add(str);
|
||||||
|
var pathJson = Newtonsoft.Json.JsonConvert.SerializeObject(Paths.ToList());
|
||||||
|
Plugin.Settings.CrossSettings.Current.AddOrUpdateValue("Paths", pathJson);
|
||||||
|
MessageBox.Show("Seccuss");
|
||||||
|
//serviceWrapper.LocalServices.ResetFolder();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ResetDbCommand = new DelegateCommand(() =>
|
||||||
|
{
|
||||||
|
QuestionDialog dialog = new QuestionDialog("ایا از ریست کردن دیتابیس مطمئن هستید ؟");
|
||||||
|
dialog.Submited += (async (ss, ee) =>
|
||||||
|
{
|
||||||
|
var context = new PlixContext();
|
||||||
|
await context.Database.EnsureDeletedAsync();
|
||||||
|
await context.Database.MigrateAsync();
|
||||||
|
});
|
||||||
|
DialogHost.OpenDialogCommand.Execute(dialog,null);
|
||||||
|
});
|
||||||
|
RemovePathCommand = new DelegateCommand<string>(str =>
|
||||||
|
{
|
||||||
|
Paths.Remove(str);
|
||||||
|
var pathJson = Newtonsoft.Json.JsonConvert.SerializeObject(Paths.ToList());
|
||||||
|
Plugin.Settings.CrossSettings.Current.AddOrUpdateValue("Paths", pathJson);
|
||||||
|
MessageBox.Show("Seccuss");
|
||||||
|
});
|
||||||
|
AddCategoryCommand = new DelegateCommand<string>(async(cat) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await repositoryWrapper.SetRepository<Category>().AddAsync(new Category
|
||||||
|
{
|
||||||
|
Name = cat
|
||||||
|
},CancellationToken.None);
|
||||||
|
MessageBox.Show("Seccuss");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageBox.Show(e.Message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ResetFolderCommand = new DelegateCommand(() =>
|
||||||
|
{
|
||||||
|
serviceWrapper.LocalServices.ResetFolder();
|
||||||
|
});
|
||||||
|
ChangeBackGroundCommand = new DelegateCommand( ()=>
|
||||||
|
{
|
||||||
|
OpenFileDialog openFileDialog = new OpenFileDialog();
|
||||||
|
openFileDialog.Multiselect = false;
|
||||||
|
openFileDialog.Filter = "Image Files(*.BMP;*.JPG;*.GIF*.PNG)|*.BMP;*.JPG;*.GIF*.PNG|All files (*.*)|*.*";
|
||||||
|
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
|
||||||
|
if (openFileDialog.ShowDialog() == true)
|
||||||
|
{
|
||||||
|
var str = openFileDialog.FileName;
|
||||||
|
if (!string.IsNullOrEmpty(str))
|
||||||
|
{
|
||||||
|
Plugin.Settings.CrossSettings.Current.AddOrUpdateValue("Background", str);
|
||||||
|
DialogHost.OpenDialogCommand.Execute(new RestartAppDialog(),null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,162 @@
|
||||||
|
using Prism.Commands;
|
||||||
|
using Prism.Mvvm;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using HandyControl.Controls;
|
||||||
|
using HandyControl.Interactivity;
|
||||||
|
using MaterialDesignThemes.Wpf;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using PlixP.Models;
|
||||||
|
using PlixP.Repositories.Contracts;
|
||||||
|
using PlixP.Services;
|
||||||
|
using PlixP.Services.Contracts;
|
||||||
|
using PlixP.Views.Dialogs;
|
||||||
|
using MessageBox = System.Windows.MessageBox;
|
||||||
|
|
||||||
|
namespace PlixP.ViewModels
|
||||||
|
{
|
||||||
|
public class MovieDialogViewModel : BindableBase
|
||||||
|
{
|
||||||
|
private Movie _movie;
|
||||||
|
public Movie Movie
|
||||||
|
{
|
||||||
|
get { return _movie; }
|
||||||
|
set { SetProperty(ref _movie, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICommand DeleteCommand { get; set; }
|
||||||
|
public ICommand SaveCommand { get; set; }
|
||||||
|
public ICommand PlayFileCommand { get; set; }
|
||||||
|
public ICommand OpenFolderCommand { get; set; }
|
||||||
|
public ICommand AddCategoryCommand { get; set; }
|
||||||
|
public ICommand RemoveCategoryCommand { get; set; }
|
||||||
|
private IServiceWrapper ServiceWrapper { get; set; }
|
||||||
|
private IRepositoryWrapper RepositoryWrapper { get; set; }
|
||||||
|
public ObservableCollection<Category> Categories { get; set; }
|
||||||
|
public List<object> Properties { get; set; } = new List<object>();
|
||||||
|
public MovieDialogViewModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
public MovieDialogViewModel(IServiceWrapper serviceWrapper, IRepositoryWrapper repositoryWrapper, Movie movie)
|
||||||
|
{
|
||||||
|
Categories = new ObservableCollection<Category>();
|
||||||
|
repositoryWrapper.SetRepository<Category>().TableNoTracking.ToList().ForEach(c => Categories.Add(c));
|
||||||
|
Movie = movie;
|
||||||
|
ServiceWrapper = serviceWrapper;
|
||||||
|
RepositoryWrapper = repositoryWrapper;
|
||||||
|
Properties.Add(new
|
||||||
|
{
|
||||||
|
Name = "Director : ",
|
||||||
|
Value = movie.Director
|
||||||
|
});
|
||||||
|
Properties.Add(new
|
||||||
|
{
|
||||||
|
Name = "Writer : ",
|
||||||
|
Value = movie.Writer
|
||||||
|
});
|
||||||
|
Properties.Add(new
|
||||||
|
{
|
||||||
|
Name = "Awarads : ",
|
||||||
|
Value = movie.Awards
|
||||||
|
});
|
||||||
|
Properties.Add(new
|
||||||
|
{
|
||||||
|
Name = "Actors : ",
|
||||||
|
Value = movie.Actors
|
||||||
|
});
|
||||||
|
Properties.Add(new
|
||||||
|
{
|
||||||
|
Name = "Country : ",
|
||||||
|
Value = movie.Country
|
||||||
|
});
|
||||||
|
DeleteCommand = new DelegateCommand(() =>
|
||||||
|
{
|
||||||
|
QuestionDialog dialog = new QuestionDialog("ایا از حذف فیلم مطمئن هستید ؟");
|
||||||
|
dialog.Submited += (async (ss, ee) =>
|
||||||
|
{
|
||||||
|
await serviceWrapper.MovieServices.DeleteMovie(movie);
|
||||||
|
ControlCommands.CloseAll.Execute(null, null);
|
||||||
|
HandyControl.Controls.MessageBox.Show($"{movie.Title} Has Removed");
|
||||||
|
});
|
||||||
|
Dialog.Show(dialog);
|
||||||
|
});
|
||||||
|
PlayFileCommand = new DelegateCommand(() =>
|
||||||
|
{
|
||||||
|
Process process = new Process();
|
||||||
|
process.StartInfo.UseShellExecute = true;
|
||||||
|
process.StartInfo.FileName = @Movie.Location + "\\" + Movie.FullName;
|
||||||
|
process.Start();
|
||||||
|
});
|
||||||
|
OpenFolderCommand = new DelegateCommand(() =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process process = new Process();
|
||||||
|
process.StartInfo.UseShellExecute = true;
|
||||||
|
process.StartInfo.FileName = @Movie.Location;
|
||||||
|
process.Start();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageBox.Show(e.Message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AddCategoryCommand = new DelegateCommand<Category>(async (category) =>
|
||||||
|
{
|
||||||
|
if (category.Id != 0)
|
||||||
|
{
|
||||||
|
if (Movie.Category.FirstOrDefault(c => c.CategoryId == category.Id) == null)
|
||||||
|
{
|
||||||
|
Movie.Category.Add(new CategoryMovie
|
||||||
|
{
|
||||||
|
MovieId = Movie.Id,
|
||||||
|
Category = category,
|
||||||
|
CategoryId = category.Id
|
||||||
|
});
|
||||||
|
await repositoryWrapper.SetRepository<CategoryMovie>().AddAsync(new CategoryMovie
|
||||||
|
{
|
||||||
|
MovieId = Movie.Id,
|
||||||
|
CategoryId = category.Id
|
||||||
|
},CancellationToken.None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Movie.Category.Add(new CategoryMovie
|
||||||
|
{
|
||||||
|
MovieId = Movie.Id,
|
||||||
|
Category = category
|
||||||
|
});
|
||||||
|
await repositoryWrapper.SetRepository<CategoryMovie>().AddAsync(new CategoryMovie
|
||||||
|
{
|
||||||
|
MovieId = Movie.Id,
|
||||||
|
Category = category
|
||||||
|
},CancellationToken.None);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
RemoveCategoryCommand = new DelegateCommand<CategoryMovie>(async (cMovie)=>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await RepositoryWrapper.SetRepository<CategoryMovie>().DeleteAsync(cMovie,CancellationToken.None);
|
||||||
|
Movie.Category.Remove(cMovie);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageBox.Show(e.Message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
SaveCommand = new DelegateCommand<Movie>(async (m) =>
|
||||||
|
{
|
||||||
|
await ServiceWrapper.MovieServices.EditMovie(m);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Prism.Commands;
|
||||||
|
using Prism.Mvvm;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace PlixP.ViewModels
|
||||||
|
{
|
||||||
|
public class MovieItemViewModel : BindableBase
|
||||||
|
{
|
||||||
|
|
||||||
|
public MovieItemViewModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,195 @@
|
||||||
|
using Prism.Commands;
|
||||||
|
using Prism.Mvvm;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using HandyControl.Controls;
|
||||||
|
using MaterialDesignThemes.Wpf;
|
||||||
|
using PlixP.Models;
|
||||||
|
using PlixP.Repositories.Contracts;
|
||||||
|
using PlixP.Services.Contracts;
|
||||||
|
using PlixP.Views.Dialogs;
|
||||||
|
using MessageBox = HandyControl.Controls.MessageBox;
|
||||||
|
|
||||||
|
namespace PlixP.ViewModels
|
||||||
|
{
|
||||||
|
public class MovieListViewModel : BindableBase
|
||||||
|
{
|
||||||
|
private readonly IServiceWrapper _serviceWrapper;
|
||||||
|
private readonly IRepositoryWrapper _repositoryWrapper;
|
||||||
|
private int pagingCount = 25;
|
||||||
|
private int currentPage = 0;
|
||||||
|
public bool IsAllActive { get; set; } = true;
|
||||||
|
public MovieListModel MovieListModel { get; set; } = new MovieListModel();
|
||||||
|
public ICommand RefreshCommand { get; set; }
|
||||||
|
public ICommand CheckByRealease { get; set; }
|
||||||
|
public ICommand MovieSelectedCommand { get; set; }
|
||||||
|
public ICommand RefreshFilesCommand { get; set; }
|
||||||
|
public ICommand CheckByAddedCommand { get; set; }
|
||||||
|
public ICommand CheckByImdbCommand { get; set; }
|
||||||
|
public ICommand GenreSelectedCommand { get; set; }
|
||||||
|
public ICommand NextPageCommand { get; set; }
|
||||||
|
public ICommand SearchCommand { get; set; }
|
||||||
|
|
||||||
|
public MovieListViewModel(IServiceWrapper serviceWrapper, IRepositoryWrapper repositoryWrapper)
|
||||||
|
{
|
||||||
|
_serviceWrapper = serviceWrapper;
|
||||||
|
_repositoryWrapper = repositoryWrapper;
|
||||||
|
Initialize();
|
||||||
|
CheckByImdbCommand = new DelegateCommand(async () =>
|
||||||
|
{
|
||||||
|
ChangeByImdb();
|
||||||
|
});
|
||||||
|
RefreshCommand = new DelegateCommand(async () =>
|
||||||
|
{
|
||||||
|
//await _serviceWrapper.MovieServices.SyncMovies();
|
||||||
|
await Initialize();
|
||||||
|
IsAllActive = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
MovieSelectedCommand = new DelegateCommand<Movie>((dataContext) =>
|
||||||
|
{
|
||||||
|
Dialog.Show(new MovieDialog() { DataContext = new MovieDialogViewModel(serviceWrapper, repositoryWrapper, dataContext) });
|
||||||
|
});
|
||||||
|
|
||||||
|
RefreshFilesCommand = new DelegateCommand(() =>
|
||||||
|
{
|
||||||
|
serviceWrapper.LocalServices.ResetFolder();
|
||||||
|
});
|
||||||
|
|
||||||
|
CheckByAddedCommand = new DelegateCommand(async () =>
|
||||||
|
{
|
||||||
|
await Initialize();
|
||||||
|
});
|
||||||
|
|
||||||
|
CheckByRealease = new DelegateCommand(() =>
|
||||||
|
{
|
||||||
|
ChangeByRelease();
|
||||||
|
});
|
||||||
|
|
||||||
|
GenreSelectedCommand = new DelegateCommand(() =>
|
||||||
|
{
|
||||||
|
var genreDialog = new GenresDialog(_serviceWrapper,_repositoryWrapper);
|
||||||
|
genreDialog.GenreSelected += (async (ss, genre) =>
|
||||||
|
{
|
||||||
|
await ChangeGenre(genre);
|
||||||
|
});
|
||||||
|
Dialog.Show(genreDialog);
|
||||||
|
});
|
||||||
|
SearchCommand = new DelegateCommand<string>(async (search) =>
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MovieListModel.UnPagedMovies.Clear();
|
||||||
|
foreach (var originalMovie in MovieListModel.OriginalMovies)
|
||||||
|
{
|
||||||
|
if (originalMovie.Title.ToLower().Contains(search.ToLower()))
|
||||||
|
MovieListModel.UnPagedMovies.Add(originalMovie);
|
||||||
|
}
|
||||||
|
MovieListModel.PageMovies.Clear();
|
||||||
|
currentPage = 0;
|
||||||
|
Pagination();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageBox.Show(e.Message);
|
||||||
|
await Initialize();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
NextPageCommand = new DelegateCommand(async () =>
|
||||||
|
{
|
||||||
|
currentPage++;
|
||||||
|
Pagination();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ChangeByImdb()
|
||||||
|
{
|
||||||
|
MovieListModel.UnPagedMovies.Clear();
|
||||||
|
MovieListModel.OriginalMovies.OrderByDescending(m =>
|
||||||
|
{
|
||||||
|
float rate;
|
||||||
|
if (float.TryParse(m.imdbRating, out rate))
|
||||||
|
return rate;
|
||||||
|
return 0;
|
||||||
|
}).ToList()
|
||||||
|
.ForEach(m => MovieListModel.UnPagedMovies.Add(m));
|
||||||
|
MovieListModel.PageMovies.Clear();
|
||||||
|
currentPage = 0;
|
||||||
|
Pagination();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ChangeGenre(List<string> genres)
|
||||||
|
{
|
||||||
|
MovieListModel.UnPagedMovies.Clear();
|
||||||
|
foreach (var genre in genres)
|
||||||
|
{
|
||||||
|
var moviesGenre = await _serviceWrapper.MovieServices.SelectByGenre(genre);
|
||||||
|
moviesGenre.ForEach(m => MovieListModel.UnPagedMovies.Add(m));
|
||||||
|
}
|
||||||
|
MovieListModel.PageMovies.Clear();
|
||||||
|
currentPage = 0;
|
||||||
|
}
|
||||||
|
private async Task ChangeGenre(string genre)
|
||||||
|
{
|
||||||
|
MovieListModel.UnPagedMovies.Clear();
|
||||||
|
var moviesGenre = await _serviceWrapper.MovieServices.SelectByGenre(genre);
|
||||||
|
moviesGenre.ForEach(m => MovieListModel.UnPagedMovies.Add(m));
|
||||||
|
MovieListModel.PageMovies.Clear();
|
||||||
|
currentPage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ChangeByRelease()
|
||||||
|
{
|
||||||
|
MovieListModel.UnPagedMovies.Clear();
|
||||||
|
MovieListModel.OriginalMovies.OrderByDescending(m => m.IntYear).ToList()
|
||||||
|
.ForEach(m => MovieListModel.UnPagedMovies.Add(m));
|
||||||
|
MovieListModel.PageMovies.Clear();
|
||||||
|
currentPage = 0;
|
||||||
|
Pagination();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Initialize()
|
||||||
|
{
|
||||||
|
MovieListModel.PageMovies.Clear();
|
||||||
|
MovieListModel.UnPagedMovies.Clear();
|
||||||
|
MovieListModel.OriginalMovies.Clear();
|
||||||
|
(await _serviceWrapper.MovieServices.GetMovies())
|
||||||
|
.OrderByDescending(m => m.CreationDate)
|
||||||
|
.ToList()
|
||||||
|
.ForEach(m =>
|
||||||
|
{
|
||||||
|
MovieListModel.OriginalMovies.Add(m);
|
||||||
|
});
|
||||||
|
|
||||||
|
MovieListModel.OriginalMovies.ToList()
|
||||||
|
.ForEach(m => MovieListModel.UnPagedMovies.Add(m));
|
||||||
|
MovieListModel.OriginalCategories = new ObservableCollection<Category>(_repositoryWrapper
|
||||||
|
.SetRepository<Category>().TableNoTracking);
|
||||||
|
MovieListModel.MoviesCount = MovieListModel.UnPagedMovies.Count;
|
||||||
|
MovieListModel.OriginalGenres = await _serviceWrapper.MovieServices.GetGenres();
|
||||||
|
currentPage = 0;
|
||||||
|
Pagination();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Pagination()
|
||||||
|
{
|
||||||
|
var selected = MovieListModel.UnPagedMovies.Skip((currentPage * pagingCount)).Take(pagingCount).ToList();
|
||||||
|
foreach (var movie in selected)
|
||||||
|
{
|
||||||
|
Application.Current.Dispatcher.Invoke(() =>
|
||||||
|
{
|
||||||
|
MovieListModel.PageMovies.Add(movie);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
using Prism.Commands;
|
||||||
|
using Prism.Mvvm;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace PlixP.ViewModels
|
||||||
|
{
|
||||||
|
public class SuggestionBoxViewModel : BindableBase
|
||||||
|
{
|
||||||
|
public SuggestionBoxViewModel()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="PlixP.Views.Dialogs.AddCategoryDialog"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
Width="350"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
|
Background="Transparent"
|
||||||
|
TextElement.FontSize="13"
|
||||||
|
TextElement.FontWeight="Regular"
|
||||||
|
TextOptions.TextFormattingMode="Ideal"
|
||||||
|
TextOptions.TextRenderingMode="Auto">
|
||||||
|
<materialDesign:Card Width="350" Padding="10" />
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace PlixP.Views.Dialogs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for AddCategoryDialog
|
||||||
|
/// </summary>
|
||||||
|
public partial class AddCategoryDialog : UserControl
|
||||||
|
{
|
||||||
|
public AddCategoryDialog()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="PlixP.Views.Dialogs.GenresDialog"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:input="clr-namespace:System.Windows.Input;assembly=PresentationCore"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:renders="clr-namespace:PlixP.Renders"
|
||||||
|
Width="870"
|
||||||
|
Height="700"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True">
|
||||||
|
|
||||||
|
|
||||||
|
<materialDesign:Card
|
||||||
|
Padding="15"
|
||||||
|
materialDesign:ShadowAssist.ShadowDepth="Depth5"
|
||||||
|
Background="{StaticResource SecondaryRegionBrush}"
|
||||||
|
UniformCornerRadius="10">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock FontSize="24" Text="Genres" />
|
||||||
|
<Button
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="0,0,0,0"
|
||||||
|
Padding="9,8,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Background="#FF5252"
|
||||||
|
BorderThickness="0"
|
||||||
|
Command="hc:ControlCommands.Close"
|
||||||
|
Foreground="White"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}">
|
||||||
|
<materialDesign:PackIcon
|
||||||
|
Width="24"
|
||||||
|
Height="24"
|
||||||
|
Kind="Close" />
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
<hc:ScrollViewer
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="0,8,0,0"
|
||||||
|
Padding="0">
|
||||||
|
<ItemsControl
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
|
ItemsSource="{Binding Genres}">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<WrapPanel Orientation="Horizontal" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
|
||||||
|
<materialDesign:Card
|
||||||
|
Margin="15"
|
||||||
|
materialDesign:ShadowAssist.ShadowDepth="Depth5"
|
||||||
|
Background="{StaticResource SecondaryRegionBrush}"
|
||||||
|
Cursor="{x:Static input:Cursors.Hand}"
|
||||||
|
MouseDown="GenreItem_OnMouseDown"
|
||||||
|
UniformCornerRadius="10">
|
||||||
|
<Grid>
|
||||||
|
<renders:ImageCacher
|
||||||
|
Width="250"
|
||||||
|
Height="150"
|
||||||
|
ImageSource="{Binding Path=Image}"
|
||||||
|
Stretch="UniformToFill" />
|
||||||
|
<Grid Background="#99222222">
|
||||||
|
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="24"
|
||||||
|
FontWeight="Light"
|
||||||
|
Text="{Binding Name}" />
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="24"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Foreground="{StaticResource PrimaryBrush}"
|
||||||
|
Text="{Binding MovieCount}" />
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</hc:ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,39 @@
|
||||||
|
using System;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using HandyControl.Controls;
|
||||||
|
using HandyControl.Interactivity;
|
||||||
|
using PlixP.Repositories.Contracts;
|
||||||
|
using PlixP.Services.Contracts;
|
||||||
|
using PlixP.ViewModels;
|
||||||
|
using Card = MaterialDesignThemes.Wpf.Card;
|
||||||
|
|
||||||
|
namespace PlixP.Views.Dialogs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for GenresDialog
|
||||||
|
/// </summary>
|
||||||
|
public partial class GenresDialog : UserControl
|
||||||
|
{
|
||||||
|
public event EventHandler<string> GenreSelected;
|
||||||
|
public GenresDialog(IServiceWrapper serviceWrapper,IRepositoryWrapper repositoryWrapper)
|
||||||
|
{
|
||||||
|
var viewModel = new GenresDialogViewModel(serviceWrapper, repositoryWrapper);
|
||||||
|
DataContext = viewModel;
|
||||||
|
viewModel.GenreSelected += ((model, genre) =>
|
||||||
|
{
|
||||||
|
GenreSelected?.Invoke(model,genre);
|
||||||
|
ControlCommands.Close.Execute(this,this);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenreItem_OnMouseDown(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if(sender is Card card && card.DataContext is GenreItemModel model && DataContext is GenresDialogViewModel viewModel)
|
||||||
|
viewModel.GenreSelectCommand.Execute(model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="PlixP.Views.Dialogs.LoadingDialog"
|
||||||
|
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:local="clr-namespace:PlixP.Views.Dialogs"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
d:DesignHeight="200"
|
||||||
|
d:DesignWidth="200"
|
||||||
|
Background="Transparent"
|
||||||
|
TextElement.FontSize="13"
|
||||||
|
TextElement.FontWeight="Regular"
|
||||||
|
TextOptions.TextFormattingMode="Ideal"
|
||||||
|
TextOptions.TextRenderingMode="Auto"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
|
||||||
|
<materialDesign:Card
|
||||||
|
Padding="10"
|
||||||
|
materialDesign:ShadowAssist.ShadowDepth="Depth5"
|
||||||
|
UniformCornerRadius="10">
|
||||||
|
<StackPanel VerticalAlignment="Center">
|
||||||
|
<ProgressBar
|
||||||
|
Width="80"
|
||||||
|
Height="80"
|
||||||
|
IsIndeterminate="True"
|
||||||
|
Value="0" />
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,15"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Text="Loading ...." />
|
||||||
|
</StackPanel>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
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.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace PlixP.Views.Dialogs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for LoadingDialog.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class LoadingDialog : UserControl
|
||||||
|
{
|
||||||
|
public LoadingDialog()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,337 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="PlixP.Views.Dialogs.MovieDialog"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:renders="clr-namespace:PlixP.Renders"
|
||||||
|
xmlns:system="clr-namespace:System;assembly=System.Runtime"
|
||||||
|
Width="950"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
|
Background="Transparent"
|
||||||
|
TextElement.FontSize="13"
|
||||||
|
TextElement.FontWeight="Regular"
|
||||||
|
TextOptions.TextFormattingMode="Ideal"
|
||||||
|
TextOptions.TextRenderingMode="Auto">
|
||||||
|
|
||||||
|
<materialDesign:Card
|
||||||
|
materialDesign:ShadowAssist.ShadowDepth="Depth5"
|
||||||
|
Background="{StaticResource SecondaryRegionBrush}"
|
||||||
|
UniformCornerRadius="10">
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<materialDesign:Card Padding="10" UniformCornerRadius="10">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<materialDesign:Card
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
UniformCornerRadius="10">
|
||||||
|
|
||||||
|
<renders:ImageCacher
|
||||||
|
Height="380"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
ImageSource="{Binding Path=Movie.Poster}" />
|
||||||
|
</materialDesign:Card>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Column="1">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Row="0"
|
||||||
|
Margin="0,8,0,8"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<TextBox
|
||||||
|
Name="titleTextBox"
|
||||||
|
Margin="8,0,0,5"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
FontSize="20"
|
||||||
|
FontWeight="Thin"
|
||||||
|
IsReadOnly="True"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Text="{Binding Path=Movie.Title, Mode=OneWay}" />
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
Margin="8"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<hc:Shield
|
||||||
|
Status="{Binding Path=Movie.imdbRating}"
|
||||||
|
Subject="IMDB"
|
||||||
|
Color="#f39c12" />
|
||||||
|
<hc:Shield
|
||||||
|
Margin="8,0,0,0"
|
||||||
|
Status="{Binding Path=Movie.Metascore}"
|
||||||
|
Subject="Meta Score"
|
||||||
|
Color="#e67e22" />
|
||||||
|
<hc:Shield
|
||||||
|
Margin="8,0"
|
||||||
|
Status="{Binding Path=Movie.Released}"
|
||||||
|
Subject="Realease"
|
||||||
|
Color="#27ae60" />
|
||||||
|
<hc:Shield
|
||||||
|
Margin="0,0"
|
||||||
|
Status="{Binding Path=Movie.Quality}"
|
||||||
|
Subject="Quality"
|
||||||
|
Color="#2980b9" />
|
||||||
|
<hc:Shield
|
||||||
|
Margin="8,0"
|
||||||
|
Status="{Binding Path=Movie.BoxOffice}"
|
||||||
|
Subject="BoxOffice"
|
||||||
|
Color="#8e44ad" />
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<Grid Grid.Row="1">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Grid Grid.Column="1" Margin="8,0">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<ItemsControl
|
||||||
|
x:Name="categoryItems"
|
||||||
|
Margin="0,10"
|
||||||
|
ItemsSource="{Binding Path=Movie.Category}">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<WrapPanel />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<hc:Tag
|
||||||
|
Content="{Binding Path=Category.Name}"
|
||||||
|
Foreground="#444"
|
||||||
|
IsSelected="True"
|
||||||
|
ShowCloseButton="True" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
|
<materialDesign:PopupBox
|
||||||
|
Name="AddCategoryPopUp"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="-45,0,0,-5"
|
||||||
|
IsEnabled="{Binding IsChecked, ElementName=PopupEnabled}"
|
||||||
|
StaysOpen="True"
|
||||||
|
Visibility="Hidden">
|
||||||
|
<materialDesign:Card Background="{StaticResource ThirdlyRegionBrush}" UniformCornerRadius="8">
|
||||||
|
|
||||||
|
<Grid Width="300" Margin="8,8,8,8">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<ComboBox
|
||||||
|
Name="categoryCombo"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="8,8,8,8"
|
||||||
|
materialDesign:HintAssist.Hint="Categoreis"
|
||||||
|
materialDesign:HintAssist.IsFloating="True"
|
||||||
|
DisplayMemberPath="Name"
|
||||||
|
ItemsSource="{Binding Categories}"
|
||||||
|
MaxDropDownHeight="200" />
|
||||||
|
<StackPanel
|
||||||
|
Grid.Row="2"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<Button Click="AddCategoryButton_OnClick" Content="Add" />
|
||||||
|
<Button Command="{x:Static materialDesign:PopupBox.ClosePopupCommand}" Content="_Cancel" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</materialDesign:PopupBox>
|
||||||
|
<Button
|
||||||
|
Name="addCategoryButton"
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="40"
|
||||||
|
Height="40"
|
||||||
|
Background="#40000000"
|
||||||
|
Click="AddCategoryButtonBase_OnClick"
|
||||||
|
Content="+"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignIconButton}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<CheckBox
|
||||||
|
x:Name="dubbedToggle"
|
||||||
|
Margin="8,0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Content="DUBBED"
|
||||||
|
IsChecked="{Binding Path=Movie.IsDubbed, Mode=OneWay}" />
|
||||||
|
<CheckBox
|
||||||
|
x:Name="seenToggle"
|
||||||
|
Margin="0,2"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Content="IsSeen"
|
||||||
|
IsChecked="{Binding Path=Movie.IsSeen, Mode=OneWay}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ItemsControl Grid.Row="2" ItemsSource="{Binding Properties}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Margin="0,5" Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
Padding="5"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="12"
|
||||||
|
FontWeight="Medium"
|
||||||
|
Text="{Binding Name}"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<TextBlock
|
||||||
|
Padding="0,5"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="11"
|
||||||
|
FontWeight="Medium"
|
||||||
|
Text="{Binding Value}"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
|
||||||
|
<Grid
|
||||||
|
Grid.Column="2"
|
||||||
|
Margin="5,5,0,5"
|
||||||
|
HorizontalAlignment="Center">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
Width="40"
|
||||||
|
Height="40"
|
||||||
|
Margin="0,0,10,0"
|
||||||
|
Padding="5,7,0,0"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Click="Edit_OnClick"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingActionMiniButton}">
|
||||||
|
<materialDesign:PackIcon Width="20" Kind="Pencil" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
Margin="0,5,0,0"
|
||||||
|
Padding="9,8,0,0"
|
||||||
|
Background="#FF5252"
|
||||||
|
BorderThickness="0"
|
||||||
|
Command="hc:ControlCommands.Close"
|
||||||
|
Foreground="White"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingActionMiniAccentButton}">
|
||||||
|
<materialDesign:PackIcon
|
||||||
|
Width="24"
|
||||||
|
Height="24"
|
||||||
|
Kind="Close" />
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
Grid.Row="1"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<Button
|
||||||
|
Padding="12,5,0,0"
|
||||||
|
Command="{Binding OpenFolderCommand}"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignIconButton}">
|
||||||
|
<materialDesign:PackIcon Kind="AttachFile" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
Width="60"
|
||||||
|
Height="60"
|
||||||
|
Padding="22,15,0,0"
|
||||||
|
Background="#40eeeeee"
|
||||||
|
Command="{Binding PlayFileCommand}"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignIconButton}">
|
||||||
|
<materialDesign:PackIcon
|
||||||
|
Width="35"
|
||||||
|
Height="35"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="DeepSkyBlue"
|
||||||
|
Kind="Play" />
|
||||||
|
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
Padding="10,5,0,0"
|
||||||
|
Command="{Binding DeleteCommand}"
|
||||||
|
Foreground="#FF5252"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignIconButton}">
|
||||||
|
<materialDesign:PackIcon Kind="Delete" />
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid Grid.Row="1" Margin="8">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Padding="5"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="12"
|
||||||
|
FontWeight="Medium"
|
||||||
|
Text="Plot : "
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<TextBlock
|
||||||
|
Grid.Column="1"
|
||||||
|
Padding="0,5"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="11"
|
||||||
|
FontWeight="Medium"
|
||||||
|
Text="{Binding Path=Movie.Plot}"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,143 @@
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Controls.Primitives;
|
||||||
|
using MaterialDesignThemes.Wpf;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using PlixP.Models;
|
||||||
|
using PlixP.ViewModels;
|
||||||
|
|
||||||
|
namespace PlixP.Views.Dialogs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MovieDialog
|
||||||
|
/// </summary>
|
||||||
|
public partial class MovieDialog : UserControl
|
||||||
|
{
|
||||||
|
public Movie Movie
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (DataContext as MovieDialogViewModel).Movie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public MovieDialog()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
seenToggle.Checked += SeenToggle_OnChecked;
|
||||||
|
dubbedToggle.Checked += DubbedToggle_OnChecked;
|
||||||
|
}
|
||||||
|
public MovieDialog(Movie dataContext)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void Edit_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var button = sender as Button;
|
||||||
|
button.Content = new PackIcon
|
||||||
|
{
|
||||||
|
Kind = PackIconKind.Check,
|
||||||
|
Width = 20
|
||||||
|
};
|
||||||
|
categoryItems.IsEnabled = true;
|
||||||
|
button.Click += AcceptEdit_Click;
|
||||||
|
titleTextBox.IsReadOnly = false;
|
||||||
|
dubbedToggle.IsEnabled = true;
|
||||||
|
seenToggle.IsEnabled = true;
|
||||||
|
addCategoryButton.IsEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AcceptEdit_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Movie newMovie = (DataContext as MovieDialogViewModel)?.Movie.Clone() as Movie;
|
||||||
|
if (Movie.Title != null && !Movie.Title.Equals(titleTextBox.Text))
|
||||||
|
{
|
||||||
|
newMovie.Title = titleTextBox.Text;
|
||||||
|
}
|
||||||
|
if (Movie.IsDubbed != dubbedToggle.IsChecked)
|
||||||
|
{
|
||||||
|
if (dubbedToggle.IsChecked == true)
|
||||||
|
{
|
||||||
|
var newName = Movie.FileName.Split('.');
|
||||||
|
string nn = "";
|
||||||
|
for (int i = 0; i < newName.Length; i++)
|
||||||
|
{
|
||||||
|
if (i == newName.Length - 1)
|
||||||
|
{
|
||||||
|
nn += "Dubbed" + ".";
|
||||||
|
}
|
||||||
|
|
||||||
|
nn += newName[i] + ".";
|
||||||
|
}
|
||||||
|
newMovie.FileName = nn;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var newName = Movie.FileName.Replace("Dubbed.", "");
|
||||||
|
newMovie.FileName = newName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Movie.IsSeen != seenToggle.IsChecked)
|
||||||
|
{
|
||||||
|
newMovie.IsSeen = seenToggle.IsChecked ?? false;
|
||||||
|
}
|
||||||
|
|
||||||
|
(DataContext as MovieDialogViewModel)?.SaveCommand.Execute(newMovie);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
MessageBox.Show(exception.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DubbedToggle_OnChecked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var toggel = sender as CheckBox;
|
||||||
|
if (!categoryItems.IsEnabled)
|
||||||
|
toggel.IsChecked = !toggel.IsChecked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SeenToggle_OnChecked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var toggel = sender as CheckBox;
|
||||||
|
if (!categoryItems.IsEnabled)
|
||||||
|
toggel.IsChecked = !toggel.IsChecked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddCategoryButtonBase_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!AddCategoryPopUp.IsPopupOpen)
|
||||||
|
AddCategoryPopUp.IsPopupOpen = true;
|
||||||
|
else
|
||||||
|
AddCategoryPopUp.IsPopupOpen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CategoryNameTextBox_OnTextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
categoryCombo.IsEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddCategoryButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (categoryCombo.SelectedValue != null)
|
||||||
|
{
|
||||||
|
var category = categoryCombo.SelectedValue as Category;
|
||||||
|
(DataContext as MovieDialogViewModel)?.AddCategoryCommand.Execute(category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveCategoryButton_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
(DataContext as MovieDialogViewModel)?.RemoveCategoryCommand.Execute((sender as Button).DataContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="PlixP.Views.Dialogs.QuestionDialog"
|
||||||
|
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:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:local="clr-namespace:PlixP.Views.Dialogs"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
<materialDesign:Card
|
||||||
|
Padding="50,20"
|
||||||
|
materialDesign:ShadowAssist.ShadowDepth="Depth5"
|
||||||
|
Background="{StaticResource RegionBrush}"
|
||||||
|
UniformCornerRadius="10">
|
||||||
|
<Grid>
|
||||||
|
<StackPanel Margin="15">
|
||||||
|
<TextBlock
|
||||||
|
Name="messageTextBlock"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="18"
|
||||||
|
FontWeight="Black"
|
||||||
|
Text="برای ایجاد تغییرات لطفا برنامه را ری استارت کنید" />
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,55,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<Button
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Command="hc:ControlCommands.Close"
|
||||||
|
CommandParameter="Sample2Cancel"
|
||||||
|
Content="انصراف"
|
||||||
|
IsCancel="True"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignOutlinedButton}" />
|
||||||
|
<Button
|
||||||
|
Margin="15,0,15,0"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
|
Click="SubmitButtonBase_OnClick"
|
||||||
|
Content="تایــــــید"
|
||||||
|
IsCancel="False"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignRaisedButton}" />
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,38 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
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.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
using HandyControl.Interactivity;
|
||||||
|
using MaterialDesignThemes.Wpf;
|
||||||
|
|
||||||
|
namespace PlixP.Views.Dialogs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for QuestionDialog.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class QuestionDialog : UserControl
|
||||||
|
{
|
||||||
|
public event EventHandler Submited;
|
||||||
|
public QuestionDialog(string message)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
messageTextBlock.Text = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubmitButtonBase_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ControlCommands.Close.Execute(null,null);
|
||||||
|
Submited?.Invoke(this,new EventArgs());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="PlixP.Views.Dialogs.RestartAppDialog"
|
||||||
|
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:local="clr-namespace:PlixP.Views.Dialogs"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
TextElement.FontSize="13"
|
||||||
|
TextElement.FontWeight="Regular"
|
||||||
|
TextOptions.TextFormattingMode="Ideal"
|
||||||
|
TextOptions.TextRenderingMode="Auto"
|
||||||
|
mc:Ignorable="d">
|
||||||
|
<Grid>
|
||||||
|
<StackPanel Margin="15">
|
||||||
|
<TextBlock
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontSize="18"
|
||||||
|
Text="برای ایجاد تغییرات لطفا برنامه را ری استارت کنید" />
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
Margin="0,20,0,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<Button
|
||||||
|
Margin="0,15"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Command="{x:Static materialDesign:DialogHost.CloseDialogCommand}"
|
||||||
|
CommandParameter="Sample2Cancel"
|
||||||
|
Content="انصراف"
|
||||||
|
IsCancel="True" />
|
||||||
|
<Button
|
||||||
|
Margin="0,15"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
|
Click="SubmitButtonBase_OnClick"
|
||||||
|
Content="تایید" />
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,35 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
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.Navigation;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
|
||||||
|
namespace PlixP.Views.Dialogs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for RestartAppDialog.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class RestartAppDialog : UserControl
|
||||||
|
{
|
||||||
|
public RestartAppDialog()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SubmitButtonBase_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Process.Start(Process.GetCurrentProcess().MainModule.FileName);
|
||||||
|
Application.Current.Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
<hc:Window
|
||||||
|
x:Class="PlixP.Views.MainWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:renders="clr-namespace:PlixP.Renders"
|
||||||
|
xmlns:template="clr-namespace:PlixP.Views.Template"
|
||||||
|
xmlns:views="clr-namespace:PlixP.Views"
|
||||||
|
Title="Plix"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
|
Icon="../Resources/PlixLogo.ico"
|
||||||
|
ShowTitle="True"
|
||||||
|
WindowState="Maximized">
|
||||||
|
<materialDesign:DrawerHost>
|
||||||
|
<Grid x:Name="mainGrid">
|
||||||
|
<renders:ImageCacher ImageSource="{Binding Background}" Stretch="UniformToFill" />
|
||||||
|
<Grid Background="#10000000" />
|
||||||
|
<ContentControl prism:RegionManager.RegionName="ContentRegion" />
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Button
|
||||||
|
Width="50"
|
||||||
|
Height="50"
|
||||||
|
Margin="50,22,15,0"
|
||||||
|
Padding="8,15,0,0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Command="{x:Static materialDesign:DrawerHost.OpenDrawerCommand}"
|
||||||
|
CommandParameter="{x:Static Dock.Left}"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingActionMiniButton}">
|
||||||
|
<materialDesign:PackIcon
|
||||||
|
Width="30"
|
||||||
|
Height="30"
|
||||||
|
Kind="Menu" />
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<materialDesign:DrawerHost.LeftDrawerContent>
|
||||||
|
<views:MasterDetail />
|
||||||
|
</materialDesign:DrawerHost.LeftDrawerContent>
|
||||||
|
</materialDesign:DrawerHost>
|
||||||
|
|
||||||
|
</hc:Window>
|
|
@ -0,0 +1,25 @@
|
||||||
|
using System;
|
||||||
|
using System.Windows;
|
||||||
|
using MaterialDesignThemes.Wpf;
|
||||||
|
using PlixP.Views.Dialogs;
|
||||||
|
using Prism.Regions;
|
||||||
|
using Window = HandyControl.Controls.Window;
|
||||||
|
|
||||||
|
namespace PlixP.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MainWindow.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class MainWindow : Window
|
||||||
|
{
|
||||||
|
public static Snackbar snackbar = new Snackbar();
|
||||||
|
public MainWindow(IRegionManager regionManager)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
DialogHost.Show(new LoadingDialog());
|
||||||
|
regionManager.RegisterViewWithRegion("ContentRegion", typeof(MovieList));
|
||||||
|
mainGrid.Children.Add(snackbar);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,173 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="PlixP.Views.MasterDetail"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
Width="450"
|
||||||
|
Padding="5"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
|
Background="#444"
|
||||||
|
TextElement.FontSize="13"
|
||||||
|
TextElement.FontWeight="Regular"
|
||||||
|
TextOptions.TextFormattingMode="Ideal"
|
||||||
|
TextOptions.TextRenderingMode="Auto">
|
||||||
|
<StackPanel Margin="15">
|
||||||
|
<Grid Margin="0,15">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBox
|
||||||
|
Name="addPathTextBox"
|
||||||
|
Grid.Column="0"
|
||||||
|
MinWidth="300"
|
||||||
|
Padding="5,3"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Text="{Binding Path}">
|
||||||
|
<materialDesign:HintAssist.Hint>
|
||||||
|
<StackPanel Margin="-2,0,0,0" Orientation="Horizontal">
|
||||||
|
<materialDesign:PackIcon Kind="Add" />
|
||||||
|
<TextBlock>
|
||||||
|
Path
|
||||||
|
</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</materialDesign:HintAssist.Hint>
|
||||||
|
</TextBox>
|
||||||
|
<Button
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="10,0"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Click="Path_OnClick"
|
||||||
|
Content="+"
|
||||||
|
Resources="{StaticResource Material}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ItemsControl ItemsSource="{Binding Paths}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Border
|
||||||
|
Margin="0,4"
|
||||||
|
Padding="5"
|
||||||
|
Background="#40444444">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBlock VerticalAlignment="Center" Text="{Binding .}" />
|
||||||
|
<Button
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="25"
|
||||||
|
Height="25"
|
||||||
|
Padding="5,4,0,0"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Background="OrangeRed"
|
||||||
|
BorderBrush="Transparent"
|
||||||
|
BorderThickness="0"
|
||||||
|
Click="RemovePathButtonBase_OnClick"
|
||||||
|
Foreground="White"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingActionButton}"
|
||||||
|
ToolTip="MaterialDesignFloatingActionMiniButton">
|
||||||
|
<materialDesign:PackIcon
|
||||||
|
Width="15"
|
||||||
|
Height="15"
|
||||||
|
Kind="Close" />
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
|
||||||
|
<Grid Margin="0,15">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<TextBox
|
||||||
|
Name="addCategoryTextBox"
|
||||||
|
Grid.Column="0"
|
||||||
|
Padding="5,3"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Resources="{StaticResource Material}">
|
||||||
|
<materialDesign:HintAssist.Hint>
|
||||||
|
<StackPanel Margin="-2,0,0,0" Orientation="Horizontal">
|
||||||
|
<materialDesign:PackIcon Kind="Add" />
|
||||||
|
<TextBlock>
|
||||||
|
Add Category
|
||||||
|
</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</materialDesign:HintAssist.Hint>
|
||||||
|
</TextBox>
|
||||||
|
<Button
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="10,0"
|
||||||
|
Click="Cat_OnClick"
|
||||||
|
Content="+"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
ToolTip="Icon" />
|
||||||
|
</Grid>
|
||||||
|
<Grid Margin="0,15">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
Command="{Binding ChangeBackGroundCommand}"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
ToolTip="Change BackGround">
|
||||||
|
<Button.Content>
|
||||||
|
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="Change BackGround" />
|
||||||
|
<materialDesign:PackIcon
|
||||||
|
Margin="10,2,10,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Kind="Wallpaper" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button.Content>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Button
|
||||||
|
Margin="0,15,8,15"
|
||||||
|
Command="{Binding ResetDbCommand}"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
ToolTip="MaterialDesignIconButton">
|
||||||
|
<Button.Content>
|
||||||
|
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="Reset Db" />
|
||||||
|
<materialDesign:PackIcon
|
||||||
|
Margin="10,4,10,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Kind="DatabaseRemove" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button.Content>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="8,15,0,15"
|
||||||
|
Command="{Binding ResetFolderCommand}"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
ToolTip="MaterialDesignIconButton">
|
||||||
|
<Button.Content>
|
||||||
|
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
|
||||||
|
<TextBlock Text="Reset Folder" />
|
||||||
|
<materialDesign:PackIcon
|
||||||
|
Margin="10,4,10,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Kind="Folder" />
|
||||||
|
</StackPanel>
|
||||||
|
</Button.Content>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,34 @@
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using PlixP.ViewModels;
|
||||||
|
|
||||||
|
namespace PlixP.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MasterDetail
|
||||||
|
/// </summary>
|
||||||
|
public partial class MasterDetail : UserControl
|
||||||
|
{
|
||||||
|
public MasterDetail()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Path_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
(DataContext as MasterDetailViewModel)?.PathCommand.Execute(addPathTextBox.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Cat_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
(DataContext as MasterDetailViewModel)?.AddCategoryCommand.Execute(addCategoryTextBox.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void RemovePathButtonBase_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if(sender is Button button && button.DataContext is string str && DataContext is MasterDetailViewModel viewModel)
|
||||||
|
viewModel.RemovePathCommand.Execute(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,198 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="PlixP.Views.MovieList"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:renders="clr-namespace:PlixP.Renders"
|
||||||
|
xmlns:template="clr-namespace:PlixP.Views.Template"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True">
|
||||||
|
<Grid>
|
||||||
|
<Grid Margin="10,25,10,0">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid
|
||||||
|
Grid.Row="0"
|
||||||
|
Height="90"
|
||||||
|
Margin="-15,-22"
|
||||||
|
Background="#40000000">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Margin="120,0,15,8" Orientation="Horizontal">
|
||||||
|
<TextBlock
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontSize="35"
|
||||||
|
FontWeight="Thin"
|
||||||
|
Text="">
|
||||||
|
<TextBlock Text="Movies" />
|
||||||
|
<TextBlock
|
||||||
|
Margin="0,5,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontSize="45"
|
||||||
|
FontWeight="Black"
|
||||||
|
Foreground="{StaticResource PrimaryBrush}"
|
||||||
|
Text="{Binding MovieListModel.MoviesCount}" />
|
||||||
|
<TextBlock Text="::" />
|
||||||
|
</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
<Grid Grid.Column="1">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<!--<Grid
|
||||||
|
Grid.Column="0"
|
||||||
|
Height="90"
|
||||||
|
Margin="10,0,30,0"
|
||||||
|
VerticalAlignment="Center">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="250" />
|
||||||
|
<ColumnDefinition Width="250" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<hc:CheckComboBox
|
||||||
|
Grid.Column="0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
hc:InfoElement.Placeholder="Category"
|
||||||
|
DisplayMemberPath="Name"
|
||||||
|
ItemsSource="{Binding MovieListModel.OriginalCategories}"
|
||||||
|
ShowClearButton="True"
|
||||||
|
ShowSelectAllButton="True"
|
||||||
|
Style="{StaticResource CheckComboBoxPlus}" />
|
||||||
|
|
||||||
|
<hc:CheckComboBox
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="5,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
hc:InfoElement.Placeholder="Genre"
|
||||||
|
ItemsSource="{Binding MovieListModel.Genres}"
|
||||||
|
SelectionChanged="GenreSelector_OnSelectionChanged"
|
||||||
|
ShowClearButton="True"
|
||||||
|
ShowSelectAllButton="True"
|
||||||
|
Style="{StaticResource CheckComboBoxPlus}" />
|
||||||
|
</Grid>-->
|
||||||
|
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="0,6,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<RadioButton
|
||||||
|
Margin="4"
|
||||||
|
hc:IconElement.Geometry="{StaticResource DownloadGeometry}"
|
||||||
|
Background="{DynamicResource SecondaryRegionBrush}"
|
||||||
|
Checked="AllToggleButton_OnChecked"
|
||||||
|
Content="ByAdded"
|
||||||
|
IsChecked="{Binding IsAllActive}"
|
||||||
|
Style="{StaticResource RadioButtonIcon}" />
|
||||||
|
<RadioButton
|
||||||
|
Margin="4"
|
||||||
|
hc:IconElement.Geometry="{StaticResource CalendarGeometry}"
|
||||||
|
Background="{DynamicResource SecondaryRegionBrush}"
|
||||||
|
Checked="ByReleaseToggleButton_OnChecked"
|
||||||
|
Content="ByRelease"
|
||||||
|
Style="{StaticResource RadioButtonIcon}" />
|
||||||
|
<RadioButton
|
||||||
|
Margin="4"
|
||||||
|
hc:IconElement.Geometry="{StaticResource StarGeometry}"
|
||||||
|
Background="{DynamicResource SecondaryRegionBrush}"
|
||||||
|
BorderThickness="1"
|
||||||
|
Checked="ByImdbRatingToggleButton_OnChecked"
|
||||||
|
Content="ByImdbRating"
|
||||||
|
Style="{StaticResource RadioButtonIcon}" />
|
||||||
|
<Button
|
||||||
|
Margin="5"
|
||||||
|
hc:IconElement.Geometry="{StaticResource InfoGeometry}"
|
||||||
|
Background="{DynamicResource SecondaryRegionBrush}"
|
||||||
|
Command="{Binding GenreSelectedCommand}"
|
||||||
|
Content="GENREs"
|
||||||
|
Style="{StaticResource ButtonPrimary}" />
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
<StackPanel
|
||||||
|
Grid.Column="3"
|
||||||
|
Margin="10,0,30,4"
|
||||||
|
Orientation="Horizontal">
|
||||||
|
<Button
|
||||||
|
Padding="6,7,0,0"
|
||||||
|
Command="{Binding RefreshCommand}"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
|
||||||
|
ToolTip="Refresh Movies">
|
||||||
|
<materialDesign:PackIcon Kind="Refresh" />
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
Margin="10,0,0,0"
|
||||||
|
Padding="8,3,0,0"
|
||||||
|
Command="{Binding RefreshFilesCommand}"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
|
||||||
|
ToolTip="Refresh Files">
|
||||||
|
<materialDesign:PackIcon Kind="FileImport" />
|
||||||
|
</Button>
|
||||||
|
</StackPanel>
|
||||||
|
<TextBox
|
||||||
|
Name="searchTextBox"
|
||||||
|
Grid.Column="4"
|
||||||
|
MinWidth="300"
|
||||||
|
Margin="10,0,30,4"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingHintTextBox}">
|
||||||
|
<materialDesign:HintAssist.Hint>
|
||||||
|
<StackPanel Margin="-2,0,0,0" Orientation="Horizontal">
|
||||||
|
<materialDesign:PackIcon Kind="Search" />
|
||||||
|
<TextBlock>
|
||||||
|
Seach
|
||||||
|
</TextBlock>
|
||||||
|
</StackPanel>
|
||||||
|
</materialDesign:HintAssist.Hint>
|
||||||
|
</TextBox>
|
||||||
|
<Button
|
||||||
|
Grid.Column="5"
|
||||||
|
Margin="15,0,50,0"
|
||||||
|
Padding="5,3,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Click="SearchButtonBase_OnClick"
|
||||||
|
Content="{materialDesign:PackIcon Search}"
|
||||||
|
Resources="{StaticResource Material}"
|
||||||
|
Style="{StaticResource MaterialDesignFloatingActionMiniButton}"
|
||||||
|
ToolTip="Icon" />
|
||||||
|
</Grid>
|
||||||
|
<ScrollViewer
|
||||||
|
Grid.Row="2"
|
||||||
|
Margin="0,25,0,4"
|
||||||
|
ScrollChanged="ScrollViewer_OnScrollChanged">
|
||||||
|
<ItemsControl
|
||||||
|
x:Name="moviesItemControl"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
ItemsSource="{Binding Path=MovieListModel.PageMovies}">
|
||||||
|
<ItemsControl.ItemsPanel>
|
||||||
|
<ItemsPanelTemplate>
|
||||||
|
<WrapPanel Orientation="Horizontal" />
|
||||||
|
</ItemsPanelTemplate>
|
||||||
|
</ItemsControl.ItemsPanel>
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<template:MovieItem Margin="8,5" MouseDown="MovieItem_OnMouseDown" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,98 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using HandyControl.Controls;
|
||||||
|
using PlixP.Models;
|
||||||
|
using PlixP.ViewModels;
|
||||||
|
using PlixP.Views.Template;
|
||||||
|
using Prism.Regions;
|
||||||
|
using MessageBox = HandyControl.Controls.MessageBox;
|
||||||
|
using ScrollViewer = System.Windows.Controls.ScrollViewer;
|
||||||
|
|
||||||
|
namespace PlixP.Views
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MovieList
|
||||||
|
/// </summary>
|
||||||
|
public partial class MovieList : UserControl
|
||||||
|
{
|
||||||
|
public ObservableCollection<Movie> Movies = new ObservableCollection<Movie>();
|
||||||
|
public MovieList(IRegionManager regionManager)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
regionManager.RegisterViewWithRegion("SuggestiontRegion", typeof(SuggestionBox));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void MovieItem_OnMouseDown(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
(DataContext as MovieListViewModel)?.MovieSelectedCommand.Execute((sender as MovieItem).DataContext as Movie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ScrollViewer_OnScrollChanged(object sender, ScrollChangedEventArgs e)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (DataContext is MovieListViewModel viewModel && sender is ScrollViewer scrollViewer && scrollViewer.VerticalOffset == scrollViewer.ScrollableHeight)
|
||||||
|
{
|
||||||
|
viewModel.NextPageCommand.Execute(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AllToggleButton_OnChecked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is RadioButton button && DataContext is MovieListViewModel viewModel)
|
||||||
|
{
|
||||||
|
if(button.IsChecked.Value==true)
|
||||||
|
viewModel.CheckByAddedCommand.Execute(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ByReleaseToggleButton_OnChecked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is RadioButton button && DataContext is MovieListViewModel viewModel)
|
||||||
|
{
|
||||||
|
if (button.IsChecked.Value == true)
|
||||||
|
viewModel.CheckByRealease.Execute(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SearchButtonBase_OnClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(searchTextBox.Text))
|
||||||
|
{
|
||||||
|
MessageBox.Show("Please Enter Movie Name");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(DataContext is MovieListViewModel viewModel)
|
||||||
|
viewModel.SearchCommand.Execute(searchTextBox.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ByImdbRatingToggleButton_OnChecked(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (sender is RadioButton button && DataContext is MovieListViewModel viewModel)
|
||||||
|
{
|
||||||
|
if (button.IsChecked.Value == true)
|
||||||
|
viewModel.CheckByImdbCommand.Execute(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GenreSelector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if(sender is CheckComboBox comboBox && comboBox.SelectedItems is IList items && DataContext is MovieListViewModel viewModel)
|
||||||
|
{
|
||||||
|
var genres = new List<string>();
|
||||||
|
for (var i = 0; i < items.Count; i++)
|
||||||
|
{
|
||||||
|
if(items[0] is string str)
|
||||||
|
genres.Add(str);
|
||||||
|
}
|
||||||
|
viewModel.GenreSelectedCommand.Execute(genres);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="PlixP.Views.Template.MovieItem"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:renders="clr-namespace:PlixP.Renders"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True">
|
||||||
|
|
||||||
|
<materialDesign:Card
|
||||||
|
Width="190"
|
||||||
|
Height="280"
|
||||||
|
Margin="12,8"
|
||||||
|
materialDesign:ShadowAssist.ShadowDepth="Depth4"
|
||||||
|
Background="#95222222"
|
||||||
|
MouseEnter="Item_OnMouseEnter"
|
||||||
|
MouseLeave="Item_OnMouseLeave"
|
||||||
|
UniformCornerRadius="10">
|
||||||
|
<Grid>
|
||||||
|
<renders:ImageCacher ImageSource="{Binding Poster}" Stretch="Fill" />
|
||||||
|
<Grid Background="#85000000" Visibility="Hidden">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="10"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontSize="17"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Text="{Binding Title}"
|
||||||
|
TextAlignment="Center"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
<Grid Grid.Row="2" HorizontalAlignment="Center">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<hc:Shield
|
||||||
|
Status="{Binding Path=imdbRating}"
|
||||||
|
Subject="IMDB"
|
||||||
|
Color="#f39c12" />
|
||||||
|
<hc:Shield
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="5,0"
|
||||||
|
Status="{Binding Path=Quality}"
|
||||||
|
Subject="Quality"
|
||||||
|
Color="#2980b9" />
|
||||||
|
</Grid>
|
||||||
|
<TextBlock
|
||||||
|
Grid.Row="3"
|
||||||
|
Height="90"
|
||||||
|
Margin="8"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
FontSize="12"
|
||||||
|
FontWeight="Medium"
|
||||||
|
Text="{Binding Plot}"
|
||||||
|
TextAlignment="Justify"
|
||||||
|
TextTrimming="CharacterEllipsis"
|
||||||
|
TextWrapping="Wrap" />
|
||||||
|
</Grid>
|
||||||
|
<Grid VerticalAlignment="Top">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<StackPanel Margin="6" Orientation="Horizontal">
|
||||||
|
<materialDesign:Card
|
||||||
|
Padding="0"
|
||||||
|
materialDesign:ShadowAssist.ShadowDepth="Depth0"
|
||||||
|
Background="LightSteelBlue"
|
||||||
|
FontWeight="Black"
|
||||||
|
Opacity="0.9"
|
||||||
|
UniformCornerRadius="8"
|
||||||
|
Visibility="Visible">
|
||||||
|
<TextBlock
|
||||||
|
Margin="10,6"
|
||||||
|
Foreground="#444"
|
||||||
|
Text="{Binding Year}" />
|
||||||
|
</materialDesign:Card>
|
||||||
|
<materialDesign:Card
|
||||||
|
Name="dubbedCard"
|
||||||
|
Margin="2,0,0,0"
|
||||||
|
Padding="0"
|
||||||
|
materialDesign:ShadowAssist.ShadowDepth="Depth0"
|
||||||
|
Background="{StaticResource PrimaryBrush}"
|
||||||
|
FontWeight="Black"
|
||||||
|
Opacity="0.9"
|
||||||
|
UniformCornerRadius="8"
|
||||||
|
Visibility="Hidden">
|
||||||
|
<TextBlock
|
||||||
|
Margin="10,6"
|
||||||
|
Foreground="#444"
|
||||||
|
Text="Dubbed" />
|
||||||
|
</materialDesign:Card>
|
||||||
|
|
||||||
|
</StackPanel>
|
||||||
|
<Ellipse
|
||||||
|
Grid.Column="1"
|
||||||
|
Width="10"
|
||||||
|
Height="10"
|
||||||
|
Margin="5,0"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Fill="{Binding SeenStatusColor}" />
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
</materialDesign:Card>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,51 @@
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using MaterialDesignThemes.Wpf;
|
||||||
|
using PlixP.Models;
|
||||||
|
|
||||||
|
namespace PlixP.Views.Template
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for MovieItem
|
||||||
|
/// </summary>
|
||||||
|
public partial class MovieItem : UserControl
|
||||||
|
{
|
||||||
|
public MovieItem()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.Property == DataContextProperty)
|
||||||
|
{
|
||||||
|
if (DataContext is Movie)
|
||||||
|
{
|
||||||
|
if ((DataContext as Movie).IsDubbed)
|
||||||
|
dubbedCard.Visibility = Visibility.Visible;
|
||||||
|
else
|
||||||
|
dubbedCard.Visibility = Visibility.Hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.OnPropertyChanged(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Item_OnMouseEnter(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
var card = sender as Card;
|
||||||
|
var grid = card.Content as Grid;
|
||||||
|
var mGrid = grid.Children[1] as Grid;
|
||||||
|
mGrid.Visibility = Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Item_OnMouseLeave(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
var card = sender as Card;
|
||||||
|
var grid = card.Content as Grid;
|
||||||
|
var mGrid = grid.Children[1] as Grid;
|
||||||
|
mGrid.Visibility = Visibility.Hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<UserControl
|
||||||
|
x:Class="PlixP.Views.Template.SuggestionBox"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
|
xmlns:prism="http://prismlibrary.com/"
|
||||||
|
xmlns:renders="clr-namespace:PlixP.Renders"
|
||||||
|
xmlns:template="clr-namespace:PlixP.Views.Template"
|
||||||
|
xmlns:views="clr-namespace:PlixP.Views"
|
||||||
|
prism:ViewModelLocator.AutoWireViewModel="True"
|
||||||
|
TextElement.FontSize="13"
|
||||||
|
TextElement.FontWeight="Regular"
|
||||||
|
TextOptions.TextFormattingMode="Ideal"
|
||||||
|
TextOptions.TextRenderingMode="Auto">
|
||||||
|
<Grid Height="180">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace PlixP.Views.Template
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for SuggestionBox
|
||||||
|
/// </summary>
|
||||||
|
public partial class SuggestionBox : UserControl
|
||||||
|
{
|
||||||
|
public SuggestionBox()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue