initial load
This commit is contained in:
63
.gitattributes
vendored
Normal file
63
.gitattributes
vendored
Normal file
@ -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
|
||||
363
.gitignore
vendored
Normal file
363
.gitignore
vendored
Normal file
@ -0,0 +1,363 @@
|
||||
## 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
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Oo]ut/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# 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
|
||||
nunit-*.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/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# 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
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# 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
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# 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
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# 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
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).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/
|
||||
|
||||
# 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
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
|
||||
namespace YouTubeViewers.Domain.Commands
|
||||
{
|
||||
public interface ICreateYouTubeViewerCommand
|
||||
{
|
||||
Task Execute(YouTubeViewer youTubeViewer);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YouTubeViewers.Domain.Commands
|
||||
{
|
||||
public interface IDeleteYouTubeViewerCommand
|
||||
{
|
||||
Task Execute(Guid id);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
|
||||
namespace YouTubeViewers.Domain.Commands
|
||||
{
|
||||
public interface IUpdateYouTubeViewerCommand
|
||||
{
|
||||
Task Execute(YouTubeViewer youTubeViewer);
|
||||
}
|
||||
}
|
||||
24
YouTubeViewers.Domain/Models/YouTubeViewer.cs
Normal file
24
YouTubeViewers.Domain/Models/YouTubeViewer.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YouTubeViewers.Domain.Models
|
||||
{
|
||||
public class YouTubeViewer
|
||||
{
|
||||
public YouTubeViewer(Guid id, string username, bool isSubscribed, bool isMember)
|
||||
{
|
||||
Id = id;
|
||||
Username = username;
|
||||
IsSubscribed = isSubscribed;
|
||||
IsMember = isMember;
|
||||
}
|
||||
|
||||
public Guid Id { get; }
|
||||
public string Username { get; }
|
||||
public bool IsSubscribed { get; }
|
||||
public bool IsMember { get; }
|
||||
}
|
||||
}
|
||||
14
YouTubeViewers.Domain/Queries/IGetAllYouTubeViewersQuery.cs
Normal file
14
YouTubeViewers.Domain/Queries/IGetAllYouTubeViewersQuery.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
|
||||
namespace YouTubeViewers.Domain.Queries
|
||||
{
|
||||
public interface IGetAllYouTubeViewersQuery
|
||||
{
|
||||
Task<IEnumerable<YouTubeViewer>> Execute();
|
||||
}
|
||||
}
|
||||
9
YouTubeViewers.Domain/YouTubeViewers.Domain.csproj
Normal file
9
YouTubeViewers.Domain/YouTubeViewers.Domain.csproj
Normal file
@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Commands;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.EntityFramework.DTOs;
|
||||
|
||||
namespace YouTubeViewers.EntityFramework.Commands
|
||||
{
|
||||
public class CreateYouTubeViewerCommand :ICreateYouTubeViewerCommand
|
||||
{
|
||||
private readonly YouTubeViewersDbContextFactory _contextFactory;
|
||||
|
||||
public CreateYouTubeViewerCommand(YouTubeViewersDbContextFactory contextFactory)
|
||||
{
|
||||
_contextFactory = contextFactory;
|
||||
}
|
||||
|
||||
public async Task Execute(YouTubeViewer youTubeViewer)
|
||||
{
|
||||
using (YouTubeViewersDbContext context = _contextFactory.Create())
|
||||
{
|
||||
YouTubeViewerDto youTubeViewerDto = new YouTubeViewerDto()
|
||||
{
|
||||
Id = youTubeViewer.Id,
|
||||
Username = youTubeViewer.Username,
|
||||
IsSubscribed = youTubeViewer.IsSubscribed,
|
||||
IsMember = youTubeViewer.IsMember,
|
||||
};
|
||||
|
||||
context.YouTubeViewers.Add(youTubeViewerDto);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Commands;
|
||||
using YouTubeViewers.EntityFramework.DTOs;
|
||||
|
||||
namespace YouTubeViewers.EntityFramework.Commands
|
||||
{
|
||||
public class DeleteYouTubeViewerCommand : IDeleteYouTubeViewerCommand
|
||||
{
|
||||
private readonly YouTubeViewersDbContextFactory _contextFactory;
|
||||
|
||||
public DeleteYouTubeViewerCommand(YouTubeViewersDbContextFactory contextFactory)
|
||||
{
|
||||
_contextFactory = contextFactory;
|
||||
}
|
||||
|
||||
public async Task Execute(Guid id)
|
||||
{
|
||||
using (YouTubeViewersDbContext context = _contextFactory.Create())
|
||||
{
|
||||
await Task.Delay(5000);
|
||||
YouTubeViewerDto youTubeViewerDto = new YouTubeViewerDto()
|
||||
{
|
||||
Id = id,
|
||||
};
|
||||
|
||||
context.YouTubeViewers.Remove(youTubeViewerDto);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Commands;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.EntityFramework.DTOs;
|
||||
|
||||
namespace YouTubeViewers.EntityFramework.Commands
|
||||
{
|
||||
public class UpdateYouTubeViewerCommand : IUpdateYouTubeViewerCommand
|
||||
{
|
||||
private readonly YouTubeViewersDbContextFactory _contextFactory;
|
||||
|
||||
public UpdateYouTubeViewerCommand(YouTubeViewersDbContextFactory contextFactory)
|
||||
{
|
||||
_contextFactory = contextFactory;
|
||||
}
|
||||
|
||||
public async Task Execute(YouTubeViewer youTubeViewer)
|
||||
{
|
||||
using (YouTubeViewersDbContext context = _contextFactory.Create())
|
||||
{
|
||||
YouTubeViewerDto youTubeViewerDto = new YouTubeViewerDto()
|
||||
{
|
||||
Id = youTubeViewer.Id,
|
||||
Username = youTubeViewer.Username,
|
||||
IsSubscribed = youTubeViewer.IsSubscribed,
|
||||
IsMember = youTubeViewer.IsMember,
|
||||
};
|
||||
|
||||
context.YouTubeViewers.Update(youTubeViewerDto);
|
||||
await context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
16
YouTubeViewers.EntityFramework/DTOs/YouTubeViewerDto.cs
Normal file
16
YouTubeViewers.EntityFramework/DTOs/YouTubeViewerDto.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YouTubeViewers.EntityFramework.DTOs
|
||||
{
|
||||
public class YouTubeViewerDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Username { get; set; }
|
||||
public bool IsSubscribed { get; set; }
|
||||
public bool IsMember { get; set; }
|
||||
}
|
||||
}
|
||||
45
YouTubeViewers.EntityFramework/Migrations/20220819131646_Initial.Designer.cs
generated
Normal file
45
YouTubeViewers.EntityFramework/Migrations/20220819131646_Initial.Designer.cs
generated
Normal file
@ -0,0 +1,45 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using YouTubeViewers.EntityFramework;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace YouTubeViewers.EntityFramework.Migrations
|
||||
{
|
||||
[DbContext(typeof(YouTubeViewersDbContext))]
|
||||
[Migration("20220819131646_Initial")]
|
||||
partial class Initial
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "6.0.8");
|
||||
|
||||
modelBuilder.Entity("YouTubeViewers.EntityFramework.DTOs.YouTubeViewerDto", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsMember")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsSubscribed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("YouTubeViewers");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace YouTubeViewers.EntityFramework.Migrations
|
||||
{
|
||||
public partial class Initial : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "YouTubeViewers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false),
|
||||
Username = table.Column<string>(type: "TEXT", nullable: false),
|
||||
IsSubscribed = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
IsMember = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_YouTubeViewers", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "YouTubeViewers");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using YouTubeViewers.EntityFramework;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace YouTubeViewers.EntityFramework.Migrations
|
||||
{
|
||||
[DbContext(typeof(YouTubeViewersDbContext))]
|
||||
partial class YouTubeViewersDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder.HasAnnotation("ProductVersion", "6.0.8");
|
||||
|
||||
modelBuilder.Entity("YouTubeViewers.EntityFramework.DTOs.YouTubeViewerDto", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsMember")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<bool>("IsSubscribed")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("YouTubeViewers");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.Domain.Queries;
|
||||
using YouTubeViewers.EntityFramework.DTOs;
|
||||
|
||||
namespace YouTubeViewers.EntityFramework.Queries
|
||||
{
|
||||
public class GetAllYouTubeViewersQuery : IGetAllYouTubeViewersQuery
|
||||
{
|
||||
private readonly YouTubeViewersDbContextFactory _contextFactory;
|
||||
|
||||
public GetAllYouTubeViewersQuery(YouTubeViewersDbContextFactory contextFactory)
|
||||
{
|
||||
_contextFactory = contextFactory;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<YouTubeViewer>> Execute()
|
||||
{
|
||||
using (YouTubeViewersDbContext context = _contextFactory.Create())
|
||||
{
|
||||
//await Task.Delay(5000);
|
||||
|
||||
IEnumerable<YouTubeViewerDto> youTubeViewerDtos = await context.YouTubeViewers.ToListAsync();
|
||||
|
||||
return youTubeViewerDtos.Select(y => new YouTubeViewer(y.Id, y.Username, y.IsSubscribed, y.IsMember));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.8" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.8">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\YouTubeViewers.Domain\YouTubeViewers.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
24
YouTubeViewers.EntityFramework/YouTubeViewersDbContext.cs
Normal file
24
YouTubeViewers.EntityFramework/YouTubeViewersDbContext.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.EntityFramework.DTOs;
|
||||
|
||||
namespace YouTubeViewers.EntityFramework
|
||||
{
|
||||
public class YouTubeViewersDbContext : DbContext
|
||||
{
|
||||
public YouTubeViewersDbContext(DbContextOptions options) : base(options) { }
|
||||
|
||||
public DbSet<YouTubeViewerDto> YouTubeViewers { get; set; }
|
||||
|
||||
//DbContextOptions options = new DbContextOptionsBuilder()
|
||||
// .UseSqlite(_connectionString)
|
||||
// .Options;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YouTubeViewers.EntityFramework
|
||||
{
|
||||
public class YouTubeViewersDbContextFactory
|
||||
{
|
||||
private readonly DbContextOptions _options;
|
||||
|
||||
public YouTubeViewersDbContextFactory(DbContextOptions options)
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
|
||||
public YouTubeViewersDbContext Create()
|
||||
{
|
||||
|
||||
return new YouTubeViewersDbContext(_options);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Design;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YouTubeViewers.EntityFramework
|
||||
{
|
||||
public class YouTubeViewersDesignTimeDbContextFactory : IDesignTimeDbContextFactory<YouTubeViewersDbContext>
|
||||
{
|
||||
public YouTubeViewersDbContext CreateDbContext(string[] args = null)
|
||||
{
|
||||
return new YouTubeViewersDbContext(new DbContextOptionsBuilder().UseSqlite("Data Source=YouTubeViewers.db").Options);
|
||||
}
|
||||
}
|
||||
}
|
||||
94
YouTubeViewers.WPF/App.xaml
Normal file
94
YouTubeViewers.WPF/App.xaml
Normal file
@ -0,0 +1,94 @@
|
||||
<Application x:Class="YouTubeViewers.WPF.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:YouTubeViewers.WPF">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<SolidColorBrush x:Key="BorderPrimary" Color="#1c1c1c" />
|
||||
|
||||
<Style x:Key="PageHeader" TargetType="TextBlock" >
|
||||
<Setter Property="FontSize" Value="32" />
|
||||
</Style>
|
||||
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Foreground" Value="White" />
|
||||
<Setter Property="Background" Value="#547AFF" />
|
||||
<Setter Property="Padding" Value="20 8" />
|
||||
<Setter Property="Cursor" Value="Hand" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="TextBlock.TextAlignment" Value="Center" />
|
||||
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Margin="{TemplateBinding Margin}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}"
|
||||
CornerRadius="3" >
|
||||
<ContentPresenter />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
|
||||
To="#2a3d82" Duration="0:0:0.1" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
|
||||
To="#547AFF" Duration="0:0:0.1" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Opacity" Value="0.7" />
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style
|
||||
x:Key="ButtonSecondary"
|
||||
BasedOn="{StaticResource {x:Type Button}}"
|
||||
TargetType="Button">
|
||||
<Setter Property="Foreground" Value="Black" />
|
||||
<Setter Property="Background" Value="#E1E1E1" />
|
||||
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
|
||||
To="#c2c2c2" Duration="0:0:0.1" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
|
||||
To="#E1E1E1" Duration="0:0:0.1" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
78
YouTubeViewers.WPF/App.xaml.cs
Normal file
78
YouTubeViewers.WPF/App.xaml.cs
Normal file
@ -0,0 +1,78 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using YouTubeViewers.Domain.Commands;
|
||||
using YouTubeViewers.Domain.Queries;
|
||||
using YouTubeViewers.EntityFramework;
|
||||
using YouTubeViewers.EntityFramework.Commands;
|
||||
using YouTubeViewers.EntityFramework.Queries;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
using YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
namespace YouTubeViewers.WPF;
|
||||
|
||||
public partial class App : Application
|
||||
{
|
||||
private readonly ModalNavigationStore _modalNavigationStore;
|
||||
private readonly YouTubeViewersDbContextFactory _youTubeViewersDbContextFactory;
|
||||
private readonly IGetAllYouTubeViewersQuery _getAllYouTubeViewersQuery;
|
||||
private readonly ICreateYouTubeViewerCommand _createYouTubeViewerCommand;
|
||||
private readonly IUpdateYouTubeViewerCommand _updateYouTubeViewerCommand;
|
||||
private readonly IDeleteYouTubeViewerCommand _deleteYouTubeViewerCommand;
|
||||
private readonly YouTubeViewersStore _youTubeViewersStore;
|
||||
private readonly SelectedYouTubeViewerStore _selectedYouTubeViewerStore;
|
||||
|
||||
public App()
|
||||
{
|
||||
string connectionString = "Data Source=YouTubeViewers.db";
|
||||
_modalNavigationStore = new ModalNavigationStore();
|
||||
_youTubeViewersDbContextFactory = new YouTubeViewersDbContextFactory(
|
||||
new DbContextOptionsBuilder()
|
||||
.UseSqlite(connectionString)
|
||||
.Options
|
||||
);
|
||||
_getAllYouTubeViewersQuery = new GetAllYouTubeViewersQuery(_youTubeViewersDbContextFactory);
|
||||
_createYouTubeViewerCommand = new CreateYouTubeViewerCommand(_youTubeViewersDbContextFactory);
|
||||
_updateYouTubeViewerCommand = new UpdateYouTubeViewerCommand(_youTubeViewersDbContextFactory);
|
||||
_deleteYouTubeViewerCommand = new DeleteYouTubeViewerCommand(_youTubeViewersDbContextFactory);
|
||||
_youTubeViewersStore = new YouTubeViewersStore(
|
||||
_getAllYouTubeViewersQuery,
|
||||
_createYouTubeViewerCommand,
|
||||
_updateYouTubeViewerCommand,
|
||||
_deleteYouTubeViewerCommand
|
||||
);
|
||||
_selectedYouTubeViewerStore = new SelectedYouTubeViewerStore(_youTubeViewersStore);
|
||||
}
|
||||
|
||||
protected override void OnStartup(StartupEventArgs e)
|
||||
{
|
||||
using(YouTubeViewersDbContext context = _youTubeViewersDbContextFactory.Create())
|
||||
{
|
||||
//context.Database.EnsureCreated();
|
||||
context.Database.Migrate();
|
||||
}
|
||||
|
||||
YouTubeViewersViewModel youTubeViewersViewModel = YouTubeViewersViewModel.LoadViewModel(
|
||||
_youTubeViewersStore,
|
||||
_selectedYouTubeViewerStore,
|
||||
_modalNavigationStore);
|
||||
|
||||
MainWindow = new MainWindow()
|
||||
{
|
||||
DataContext = new MainViewModel(_modalNavigationStore, youTubeViewersViewModel)
|
||||
};
|
||||
|
||||
MainWindow.Show();
|
||||
|
||||
base.OnStartup(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
10
YouTubeViewers.WPF/AssemblyInfo.cs
Normal file
10
YouTubeViewers.WPF/AssemblyInfo.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
||||
50
YouTubeViewers.WPF/Commands/AddYouTubeViewerCommand.cs
Normal file
50
YouTubeViewers.WPF/Commands/AddYouTubeViewerCommand.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
using YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
namespace YouTubeViewers.WPF.Commands
|
||||
{
|
||||
public class AddYouTubeViewerCommand : AsyncCommandBase
|
||||
{
|
||||
private readonly AddYouTubeViewerViewModel _addYouTubeViewerViewModel;
|
||||
private readonly YouTubeViewersStore _youTubeViewersStore;
|
||||
private readonly ModalNavigationStore _modalNavigationStore;
|
||||
|
||||
public AddYouTubeViewerCommand(AddYouTubeViewerViewModel addYouTubeViewerViewModel, YouTubeViewersStore youTubeViewersStore, ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
_addYouTubeViewerViewModel = addYouTubeViewerViewModel;
|
||||
_youTubeViewersStore = youTubeViewersStore;
|
||||
_modalNavigationStore = modalNavigationStore;
|
||||
}
|
||||
public override async Task ExecuteAsync(object? parameter)
|
||||
{
|
||||
YouTubeViewerDetailsFormViewModel formViewModel = _addYouTubeViewerViewModel.YouTubeViewerDetailsFormViewModel;
|
||||
formViewModel.IsSubmitting = true;
|
||||
YouTubeViewer youTubeViewer = new YouTubeViewer(
|
||||
Guid.NewGuid(),
|
||||
formViewModel.UserName,
|
||||
formViewModel.IsSubScribed,
|
||||
formViewModel.IsMember);
|
||||
|
||||
// Add YouTubeViewer to database
|
||||
try
|
||||
{
|
||||
await _youTubeViewersStore.Add(youTubeViewer);
|
||||
_modalNavigationStore.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
formViewModel.IsSubmitting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
YouTubeViewers.WPF/Commands/AsyncCommandBase.cs
Normal file
44
YouTubeViewers.WPF/Commands/AsyncCommandBase.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YouTubeViewers.WPF.Commands
|
||||
{
|
||||
public abstract class AsyncCommandBase : CommandBase
|
||||
{
|
||||
private bool _isExecuting;
|
||||
|
||||
public bool IsExecuting
|
||||
{
|
||||
get { return _isExecuting; }
|
||||
set { _isExecuting = value;
|
||||
OnCanExecuteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanExecute(object? parameter)
|
||||
{
|
||||
return !_isExecuting && base.CanExecute(parameter);
|
||||
}
|
||||
|
||||
|
||||
public override async void Execute(object? parameter)
|
||||
{
|
||||
IsExecuting = true;
|
||||
|
||||
try
|
||||
{
|
||||
await ExecuteAsync(parameter);
|
||||
}
|
||||
catch (Exception) { }
|
||||
finally
|
||||
{
|
||||
IsExecuting = false;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Task ExecuteAsync(object? parameter);
|
||||
}
|
||||
}
|
||||
24
YouTubeViewers.WPF/Commands/CloseModalCommand.cs
Normal file
24
YouTubeViewers.WPF/Commands/CloseModalCommand.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
|
||||
namespace YouTubeViewers.WPF.Commands
|
||||
{
|
||||
public class CloseModalCommand : CommandBase
|
||||
{
|
||||
private readonly ModalNavigationStore _modalNavigationStore;
|
||||
|
||||
public CloseModalCommand(ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
_modalNavigationStore = modalNavigationStore;
|
||||
}
|
||||
|
||||
public override void Execute(object? parameter)
|
||||
{
|
||||
_modalNavigationStore.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
26
YouTubeViewers.WPF/Commands/CommandBase.cs
Normal file
26
YouTubeViewers.WPF/Commands/CommandBase.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace YouTubeViewers.WPF.Commands
|
||||
{
|
||||
public abstract class CommandBase : ICommand
|
||||
{
|
||||
public event EventHandler? CanExecuteChanged;
|
||||
|
||||
public virtual bool CanExecute(object? parameter)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract void Execute(object? parameter);
|
||||
|
||||
protected virtual void OnCanExecuteChanged()
|
||||
{
|
||||
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
}
|
||||
39
YouTubeViewers.WPF/Commands/DeleteYouTubeViewerCommand.cs
Normal file
39
YouTubeViewers.WPF/Commands/DeleteYouTubeViewerCommand.cs
Normal file
@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
using YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
namespace YouTubeViewers.WPF.Commands
|
||||
{
|
||||
public class DeleteYouTubeViewerCommand : AsyncCommandBase
|
||||
{
|
||||
private readonly YouTubeViewersListingItemViewModel _youTubeViewersListingItemViewModel;
|
||||
private readonly YouTubeViewersStore _youTubeViewersStore;
|
||||
|
||||
public DeleteYouTubeViewerCommand(
|
||||
YouTubeViewersListingItemViewModel youTubeViewersListingItemViewModel,
|
||||
YouTubeViewersStore youTubeViewersStore)
|
||||
{
|
||||
_youTubeViewersListingItemViewModel = youTubeViewersListingItemViewModel;
|
||||
_youTubeViewersStore = youTubeViewersStore;
|
||||
|
||||
}
|
||||
|
||||
public override async Task ExecuteAsync(object? parameter)
|
||||
{
|
||||
YouTubeViewer youTubeViewer = _youTubeViewersListingItemViewModel.YouTubeViewer;
|
||||
try
|
||||
{
|
||||
await _youTubeViewersStore.Delete(youTubeViewer.Id);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
50
YouTubeViewers.WPF/Commands/EditYouTubeViewerCommand.cs
Normal file
50
YouTubeViewers.WPF/Commands/EditYouTubeViewerCommand.cs
Normal file
@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
using YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
namespace YouTubeViewers.WPF.Commands
|
||||
{
|
||||
public class EditYouTubeViewerCommand : AsyncCommandBase
|
||||
{
|
||||
private readonly EditYouTubeViewerViewModel _editYouTubeViewerViewModel;
|
||||
private readonly YouTubeViewersStore _youTubeViewersStore;
|
||||
private readonly ModalNavigationStore _modalNavigationStore;
|
||||
|
||||
public EditYouTubeViewerCommand(EditYouTubeViewerViewModel editYouTubeViewerViewModel, YouTubeViewersStore youTubeViewersStore, ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
_editYouTubeViewerViewModel = editYouTubeViewerViewModel;
|
||||
_youTubeViewersStore = youTubeViewersStore;
|
||||
_modalNavigationStore = modalNavigationStore;
|
||||
}
|
||||
public override async Task ExecuteAsync(object? parameter)
|
||||
{
|
||||
YouTubeViewerDetailsFormViewModel formViewModel = _editYouTubeViewerViewModel.YouTubeViewerDetailsFormViewModel;
|
||||
formViewModel.IsSubmitting = true;
|
||||
YouTubeViewer youTubeViewer = new YouTubeViewer(
|
||||
_editYouTubeViewerViewModel.YouTubeViewerId,
|
||||
formViewModel.UserName,
|
||||
formViewModel.IsSubScribed,
|
||||
formViewModel.IsMember);
|
||||
|
||||
// Add YouTubeViewer to database
|
||||
try
|
||||
{
|
||||
await _youTubeViewersStore.Update(youTubeViewer);
|
||||
_modalNavigationStore.Close();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
formViewModel.IsSubmitting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
40
YouTubeViewers.WPF/Commands/LoadYouTubeViewersCommand.cs
Normal file
40
YouTubeViewers.WPF/Commands/LoadYouTubeViewersCommand.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
using YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
namespace YouTubeViewers.WPF.Commands
|
||||
{
|
||||
public class LoadYouTubeViewersCommand : AsyncCommandBase
|
||||
{
|
||||
private readonly YouTubeViewersViewModel _youTubeViewersViewModel;
|
||||
private readonly YouTubeViewersStore _youTubeViewersStore;
|
||||
|
||||
public LoadYouTubeViewersCommand(YouTubeViewersViewModel youTubeViewersViewModel, YouTubeViewersStore youTubeViewersStore)
|
||||
{
|
||||
_youTubeViewersViewModel = youTubeViewersViewModel;
|
||||
_youTubeViewersStore = youTubeViewersStore;
|
||||
}
|
||||
|
||||
public override async Task ExecuteAsync(object? parameter)
|
||||
{
|
||||
_youTubeViewersViewModel.IsLoading = true;
|
||||
|
||||
try
|
||||
{
|
||||
await _youTubeViewersStore.Load();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_youTubeViewersViewModel.IsLoading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
29
YouTubeViewers.WPF/Commands/OpenAddYouTubeViewerCommand.cs
Normal file
29
YouTubeViewers.WPF/Commands/OpenAddYouTubeViewerCommand.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
using YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
namespace YouTubeViewers.WPF.Commands
|
||||
{
|
||||
public class OpenAddYouTubeViewerCommand : CommandBase
|
||||
{
|
||||
private readonly YouTubeViewersStore _youTubeViewersStore;
|
||||
private readonly ModalNavigationStore _modalNavigationStore;
|
||||
|
||||
public OpenAddYouTubeViewerCommand(YouTubeViewersStore youTubeViewersStore, ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
_youTubeViewersStore = youTubeViewersStore;
|
||||
_modalNavigationStore = modalNavigationStore;
|
||||
}
|
||||
|
||||
public override void Execute(object? parameter)
|
||||
{
|
||||
AddYouTubeViewerViewModel addYouTubeViewerViewModel = new AddYouTubeViewerViewModel(_youTubeViewersStore, _modalNavigationStore);
|
||||
_modalNavigationStore.CurrentViewModel = addYouTubeViewerViewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
38
YouTubeViewers.WPF/Commands/OpenEditYouTubeViewerCommand.cs
Normal file
38
YouTubeViewers.WPF/Commands/OpenEditYouTubeViewerCommand.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
using YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
namespace YouTubeViewers.WPF.Commands
|
||||
{
|
||||
public class OpenEditYouTubeViewerCommand: CommandBase
|
||||
{
|
||||
private readonly YouTubeViewersListingItemViewModel _youTubeViewersListingItemViewModel;
|
||||
private readonly YouTubeViewersStore _youTubeViewersStore;
|
||||
private readonly ModalNavigationStore _modalNavigationStore;
|
||||
|
||||
public OpenEditYouTubeViewerCommand(
|
||||
YouTubeViewersListingItemViewModel youTubeViewersListingItemViewModel,
|
||||
YouTubeViewersStore youTubeViewersStore,
|
||||
ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
_youTubeViewersListingItemViewModel = youTubeViewersListingItemViewModel;
|
||||
_youTubeViewersStore = youTubeViewersStore;
|
||||
_modalNavigationStore = modalNavigationStore;
|
||||
}
|
||||
|
||||
public override void Execute(object? parameter)
|
||||
{
|
||||
YouTubeViewer youTubeViewer = _youTubeViewersListingItemViewModel.YouTubeViewer;
|
||||
|
||||
EditYouTubeViewerViewModel editYouTubeViewerViewModel = new EditYouTubeViewerViewModel(youTubeViewer,_youTubeViewersStore, _modalNavigationStore);
|
||||
_modalNavigationStore.CurrentViewModel = editYouTubeViewerViewModel;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
70
YouTubeViewers.WPF/Components/YouTubeViewerDetailsForm.xaml
Normal file
70
YouTubeViewers.WPF/Components/YouTubeViewerDetailsForm.xaml
Normal file
@ -0,0 +1,70 @@
|
||||
<UserControl x:Class="YouTubeViewers.WPF.Components.YouTubeViewerDetailsForm"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:YouTubeViewers.WPF.Components"
|
||||
xmlns:custom="clr-namespace:LoadingSpinnerControl;assembly=LoadingSpinnerControl"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.IsSharedSizeScope="True">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
|
||||
<Grid Grid.Row="0" >
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" SharedSizeGroup="Label"/>
|
||||
<ColumnDefinition Width="*" MaxWidth="250"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Username" FontWeight="Bold" />
|
||||
<TextBox Margin="20 0 0 0"
|
||||
Grid.Column="1"
|
||||
Text="{Binding UserName, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Margin="0 20 0 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" SharedSizeGroup="Label"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Is Subscribed?" FontWeight="Bold" />
|
||||
<CheckBox Margin="20 0 0 0"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
IsChecked="{Binding IsSubScribed}" />
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="2" Margin="0 20 0 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" SharedSizeGroup="Label"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Is Member?" FontWeight="Bold" />
|
||||
<CheckBox Margin="20 0 0 0"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
IsChecked="{Binding IsMember}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
<WrapPanel Grid.Row="1" Margin="0 30 0 0">
|
||||
<Button Margin="0 0 5 0"
|
||||
Command="{Binding SubmitCommand}"
|
||||
Content="Submit"
|
||||
IsEnabled="{Binding CanSubmit}"/>
|
||||
|
||||
<Button Margin="0 0 5 0" Command="{Binding CancelCommand}"
|
||||
Content="Cancel"
|
||||
Style="{StaticResource ButtonSecondary}"/>
|
||||
<custom:LoadingSpinner IsLoading="{Binding IsSubmitting}" Diameter="25" Thickness="2"/>
|
||||
</WrapPanel>
|
||||
</Grid>
|
||||
</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 YouTubeViewers.WPF.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for YouTubeViewerDetailsForm.xaml
|
||||
/// </summary>
|
||||
public partial class YouTubeViewerDetailsForm : UserControl
|
||||
{
|
||||
public YouTubeViewerDetailsForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
73
YouTubeViewers.WPF/Components/YouTubeViewersDetails.xaml
Normal file
73
YouTubeViewers.WPF/Components/YouTubeViewersDetails.xaml
Normal file
@ -0,0 +1,73 @@
|
||||
<UserControl x:Class="YouTubeViewers.WPF.Components.YouTubeViewersDetails"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:YouTubeViewers.WPF.Components"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Border Padding="20" BorderBrush="{StaticResource BorderPrimary}"
|
||||
BorderThickness="1" CornerRadius="5"
|
||||
SnapsToDevicePixels="True">
|
||||
<Grid>
|
||||
<Grid>
|
||||
<Grid.Style>
|
||||
<Style TargetType="Grid">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasSelectedYouTubeViewer}" Value="false">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
<TextBlock Grid.Row="0"
|
||||
Text="Please select a YouTube Viewer to see their details." />
|
||||
</Grid>
|
||||
<Grid Grid.IsSharedSizeScope="True">
|
||||
<Grid.Style>
|
||||
<Style TargetType="Grid">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasSelectedYouTubeViewer}" Value="True">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock Grid.Row="0"
|
||||
FontSize="24"
|
||||
Text="{Binding UserName}" />
|
||||
|
||||
<Grid Grid.Row="1" Margin="0 20 0 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" SharedSizeGroup="Label"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Is Subscribed?" FontWeight="Bold" />
|
||||
<TextBlock Margin="20 0 0 0"
|
||||
Grid.Column="1"
|
||||
Text="{Binding IsSubScribedDisplay}" />
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="2" Margin="0 20 0 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto" SharedSizeGroup="Label"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="Is Member?" FontWeight="Bold" />
|
||||
<TextBlock Margin="20 0 0 0"
|
||||
Grid.Column="1"
|
||||
Text="{Binding IsMemberDisplay}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
28
YouTubeViewers.WPF/Components/YouTubeViewersDetails.xaml.cs
Normal file
28
YouTubeViewers.WPF/Components/YouTubeViewersDetails.xaml.cs
Normal file
@ -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 YouTubeViewers.WPF.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for YouTubeViewersDetails.xaml
|
||||
/// </summary>
|
||||
public partial class YouTubeViewersDetails : UserControl
|
||||
{
|
||||
public YouTubeViewersDetails()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
41
YouTubeViewers.WPF/Components/YouTubeViewersListing.xaml
Normal file
41
YouTubeViewers.WPF/Components/YouTubeViewersListing.xaml
Normal file
@ -0,0 +1,41 @@
|
||||
<UserControl x:Class="YouTubeViewers.WPF.Components.YouTubeViewersListing"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:YouTubeViewers.WPF.Components"
|
||||
xmlns:custom="clr-namespace:DropdownMenuControl;assembly=DropdownMenuControl"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Border
|
||||
BorderBrush="{StaticResource BorderPrimary}"
|
||||
BorderThickness="1"
|
||||
CornerRadius="5"
|
||||
SnapsToDevicePixels="True">
|
||||
<Grid>
|
||||
<Grid.OpacityMask>
|
||||
<VisualBrush Visual="{Binding ElementName=border}"/>
|
||||
</Grid.OpacityMask>
|
||||
<Border
|
||||
x:Name="border"
|
||||
Background="White"
|
||||
CornerRadius="5"/>
|
||||
<ListView BorderThickness="0"
|
||||
ItemsSource="{Binding YouTubeViewersListingItemViewModels}"
|
||||
SelectedItem="{Binding SelectedYouTubeViewerListingItemViewModel}">
|
||||
<ListView.ItemContainerStyle>
|
||||
<Style TargetType="ListViewItem">
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
</Style>
|
||||
</ListView.ItemContainerStyle>
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<local:YouTubeViewersListingItem/>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
28
YouTubeViewers.WPF/Components/YouTubeViewersListing.xaml.cs
Normal file
28
YouTubeViewers.WPF/Components/YouTubeViewersListing.xaml.cs
Normal file
@ -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 YouTubeViewers.WPF.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for YouTubeViewersListing.xaml
|
||||
/// </summary>
|
||||
public partial class YouTubeViewersListing : UserControl
|
||||
{
|
||||
public YouTubeViewersListing()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
80
YouTubeViewers.WPF/Components/YouTubeViewersListingItem.xaml
Normal file
80
YouTubeViewers.WPF/Components/YouTubeViewersListingItem.xaml
Normal file
@ -0,0 +1,80 @@
|
||||
<UserControl x:Class="YouTubeViewers.WPF.Components.YouTubeViewersListingItem"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:YouTubeViewers.WPF.Components"
|
||||
xmlns:custom="clr-namespace:DropdownMenuControl;assembly=DropdownMenuControl"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Border Padding="10" TextBlock.FontSize="16">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Text="{Binding UserName}"/>
|
||||
|
||||
<custom:DropdownMenu x:Name="dropdown" Grid.Column="1" Margin="10 0 0 0">
|
||||
<Border
|
||||
Background="White"
|
||||
BorderThickness="1"
|
||||
BorderBrush="Gray">
|
||||
<StackPanel MinWidth="125">
|
||||
<StackPanel.Resources>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="Background" Value="#f0f0f0"/>
|
||||
<Setter Property="Foreground" Value="Black"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="Padding" Value="20 10"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<EventSetter Event="Click" Handler="Button_Click"/>
|
||||
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border
|
||||
Margin="{TemplateBinding Margin}"
|
||||
Padding="{TemplateBinding Padding}"
|
||||
Background="{TemplateBinding Background}">
|
||||
<ContentPresenter />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Trigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
|
||||
To="#c7c7c7"
|
||||
Duration="0:0:0.1" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.EnterActions>
|
||||
<Trigger.ExitActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<ColorAnimation
|
||||
Storyboard.TargetProperty="Background.(SolidColorBrush.Color)"
|
||||
To="#f0f0f0"
|
||||
Duration="0:0:0.1" />
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</Trigger.ExitActions>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</StackPanel.Resources>
|
||||
<Button Content="Edit" Command="{Binding EditCommand}"/>
|
||||
<Button Content="Delete" Command="{Binding DeleteCommand}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</custom:DropdownMenu>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@ -0,0 +1,33 @@
|
||||
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 YouTubeViewers.WPF.Components
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for YouTubeViewersListingItem.xaml
|
||||
/// </summary>
|
||||
public partial class YouTubeViewersListingItem : UserControl
|
||||
{
|
||||
public YouTubeViewersListingItem()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
dropdown.IsOpen = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
34
YouTubeViewers.WPF/MainWindow.xaml
Normal file
34
YouTubeViewers.WPF/MainWindow.xaml
Normal file
@ -0,0 +1,34 @@
|
||||
<Window x:Class="YouTubeViewers.WPF.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:YouTubeViewers.WPF"
|
||||
xmlns:vms ="clr-namespace:YouTubeViewers.WPF.ViewModels"
|
||||
xmlns:views="clr-namespace:YouTubeViewers.WPF.Views"
|
||||
xmlns:viewmodels="clr-namespace:YouTubeViewers.WPF.ViewModels"
|
||||
xmlns:custom="clr-namespace:ModalControl;assembly=ModalControl"
|
||||
mc:Ignorable="d"
|
||||
Title="YouTube Viewers"
|
||||
Height="450"
|
||||
Width="800"
|
||||
FontSize="14"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Window.Resources>
|
||||
<DataTemplate DataType="{x:Type vms:AddYouTubeViewerViewModel}">
|
||||
<views:AddYouTubeViewerView/>
|
||||
</DataTemplate>
|
||||
<DataTemplate DataType="{x:Type vms:EditYouTubeViewerViewModel}">
|
||||
<views:EditYouTubeViewerView/>
|
||||
</DataTemplate>
|
||||
</Window.Resources>
|
||||
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
|
||||
<Grid >
|
||||
<custom:Modal Panel.ZIndex="1" IsOpen="{Binding IsModalOpen}">
|
||||
<ContentControl Margin="50 25" Content="{Binding CurrentModalViewModel}"/>
|
||||
</custom:Modal>
|
||||
|
||||
<views:YouTubeViewersView Margin="25" DataContext="{Binding YouTubeViewersViewModel}" />
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
</Window>
|
||||
28
YouTubeViewers.WPF/MainWindow.xaml.cs
Normal file
28
YouTubeViewers.WPF/MainWindow.xaml.cs
Normal file
@ -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 YouTubeViewers.WPF
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
28
YouTubeViewers.WPF/Stores/ModalNavigationStore.cs
Normal file
28
YouTubeViewers.WPF/Stores/ModalNavigationStore.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
namespace YouTubeViewers.WPF.Stores
|
||||
{
|
||||
public class ModalNavigationStore
|
||||
{
|
||||
private ViewModelBase _currentViewModel;
|
||||
|
||||
public ViewModelBase CurrentViewModel
|
||||
{
|
||||
get { return _currentViewModel; }
|
||||
set {
|
||||
_currentViewModel = value;
|
||||
CurrentViewModelChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsOpen => CurrentViewModel != null;
|
||||
|
||||
public event Action CurrentViewModelChanged;
|
||||
|
||||
public void Close()
|
||||
{
|
||||
CurrentViewModel = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
43
YouTubeViewers.WPF/Stores/SelectedYouTubeViewerStore.cs
Normal file
43
YouTubeViewers.WPF/Stores/SelectedYouTubeViewerStore.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
|
||||
namespace YouTubeViewers.WPF.Stores
|
||||
{
|
||||
public class SelectedYouTubeViewerStore
|
||||
{
|
||||
private readonly YouTubeViewersStore _youTubeViewersStore;
|
||||
|
||||
public SelectedYouTubeViewerStore(YouTubeViewersStore youTubeViewersStore)
|
||||
{
|
||||
_youTubeViewersStore = youTubeViewersStore;
|
||||
_youTubeViewersStore.YouTubeViewerUpdated += YouTubeViewersStore_YouTubeViewerUpdated;
|
||||
}
|
||||
|
||||
private void YouTubeViewersStore_YouTubeViewerUpdated(YouTubeViewer youTubeViewer)
|
||||
{
|
||||
if (youTubeViewer.Id == SelectedYouTubeViewer?.Id)
|
||||
{
|
||||
SelectedYouTubeViewer = youTubeViewer;
|
||||
}
|
||||
}
|
||||
|
||||
private YouTubeViewer _selectedYouTubeViewer;
|
||||
|
||||
public YouTubeViewer SelectedYouTubeViewer
|
||||
{
|
||||
get { return _selectedYouTubeViewer; }
|
||||
set
|
||||
{
|
||||
_selectedYouTubeViewer = value;
|
||||
SelectedYouTubeViewerChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public event Action SelectedYouTubeViewerChanged;
|
||||
|
||||
}
|
||||
}
|
||||
88
YouTubeViewers.WPF/Stores/YouTubeViewersStore.cs
Normal file
88
YouTubeViewers.WPF/Stores/YouTubeViewersStore.cs
Normal file
@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.Domain.Commands;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.Domain.Queries;
|
||||
|
||||
namespace YouTubeViewers.WPF.Stores
|
||||
{
|
||||
public class YouTubeViewersStore
|
||||
{
|
||||
private readonly IGetAllYouTubeViewersQuery _getAllYouTubeViewersQuery;
|
||||
private readonly ICreateYouTubeViewerCommand _createYouTubeViewerCommand;
|
||||
private readonly IUpdateYouTubeViewerCommand _updateYouTubeViewerCommand;
|
||||
private readonly IDeleteYouTubeViewerCommand _deleteYouTubeViewerCommand;
|
||||
private readonly List<YouTubeViewer> _youTubeViewers;
|
||||
|
||||
public IEnumerable<YouTubeViewer> YouTubeViewers => _youTubeViewers;
|
||||
|
||||
public event Action YouTubeViewersLoaded;
|
||||
public event Action<YouTubeViewer> YouTubeViewerAdded;
|
||||
public event Action<YouTubeViewer> YouTubeViewerUpdated;
|
||||
public event Action<Guid> YouTubeViewerDeleted;
|
||||
|
||||
|
||||
public YouTubeViewersStore(
|
||||
IGetAllYouTubeViewersQuery getAllYouTubeViewersQuery,
|
||||
ICreateYouTubeViewerCommand createYouTubeViewerCommand,
|
||||
IUpdateYouTubeViewerCommand updateYouTubeViewerCommand,
|
||||
IDeleteYouTubeViewerCommand deleteYouTubeViewerCommand)
|
||||
{
|
||||
_getAllYouTubeViewersQuery = getAllYouTubeViewersQuery;
|
||||
_createYouTubeViewerCommand = createYouTubeViewerCommand;
|
||||
_updateYouTubeViewerCommand = updateYouTubeViewerCommand;
|
||||
_deleteYouTubeViewerCommand = deleteYouTubeViewerCommand;
|
||||
|
||||
_youTubeViewers = new List<YouTubeViewer>();
|
||||
}
|
||||
|
||||
public async Task Load()
|
||||
{
|
||||
IEnumerable<YouTubeViewer> youTubeViewers = await _getAllYouTubeViewersQuery.Execute();
|
||||
_youTubeViewers.Clear();
|
||||
_youTubeViewers.AddRange(youTubeViewers);
|
||||
|
||||
YouTubeViewersLoaded?.Invoke();
|
||||
}
|
||||
|
||||
public async Task Add(YouTubeViewer youTubeViewer)
|
||||
{
|
||||
await _createYouTubeViewerCommand.Execute(youTubeViewer);
|
||||
|
||||
_youTubeViewers.Add(youTubeViewer);
|
||||
|
||||
YouTubeViewerAdded?.Invoke(youTubeViewer);
|
||||
}
|
||||
|
||||
public async Task Update(YouTubeViewer youTubeViewer)
|
||||
{
|
||||
await _updateYouTubeViewerCommand.Execute(youTubeViewer);
|
||||
|
||||
int currentIndex = _youTubeViewers.FindIndex(y => y.Id == youTubeViewer.Id);
|
||||
|
||||
if(currentIndex != -1)
|
||||
{
|
||||
_youTubeViewers[currentIndex] = youTubeViewer;
|
||||
}
|
||||
else
|
||||
{
|
||||
_youTubeViewers.Add(youTubeViewer);
|
||||
}
|
||||
|
||||
YouTubeViewerUpdated?.Invoke(youTubeViewer);
|
||||
}
|
||||
|
||||
public async Task Delete(Guid id)
|
||||
{
|
||||
await _deleteYouTubeViewerCommand.Execute(id);
|
||||
|
||||
_youTubeViewers.RemoveAll(y => y.Id == id);
|
||||
|
||||
YouTubeViewerDeleted?.Invoke(id);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
23
YouTubeViewers.WPF/ViewModels/AddYouTubeViewerViewModel.cs
Normal file
23
YouTubeViewers.WPF/ViewModels/AddYouTubeViewerViewModel.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using YouTubeViewers.WPF.Commands;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
|
||||
namespace YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
public class AddYouTubeViewerViewModel : ViewModelBase
|
||||
{
|
||||
public YouTubeViewerDetailsFormViewModel YouTubeViewerDetailsFormViewModel { get; }
|
||||
|
||||
public AddYouTubeViewerViewModel(YouTubeViewersStore _youTubeViewersStore, ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
ICommand cancelCommand = new CloseModalCommand( modalNavigationStore);
|
||||
ICommand submitCommand = new AddYouTubeViewerCommand(this , _youTubeViewersStore,modalNavigationStore);
|
||||
YouTubeViewerDetailsFormViewModel = new YouTubeViewerDetailsFormViewModel(submitCommand,cancelCommand);
|
||||
}
|
||||
|
||||
}
|
||||
32
YouTubeViewers.WPF/ViewModels/EditYouTubeViewerViewModel.cs
Normal file
32
YouTubeViewers.WPF/ViewModels/EditYouTubeViewerViewModel.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using YouTubeViewers.WPF.Commands;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
|
||||
namespace YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
public class EditYouTubeViewerViewModel : ViewModelBase
|
||||
{
|
||||
public Guid YouTubeViewerId { get; }
|
||||
|
||||
public YouTubeViewerDetailsFormViewModel YouTubeViewerDetailsFormViewModel { get; }
|
||||
|
||||
public EditYouTubeViewerViewModel(YouTubeViewer youTubeViewer, YouTubeViewersStore _youTubeViewersStore, ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
YouTubeViewerId = youTubeViewer.Id;
|
||||
|
||||
ICommand submitCommand = new EditYouTubeViewerCommand(this, _youTubeViewersStore, modalNavigationStore);
|
||||
ICommand cancelCommand = new CloseModalCommand(modalNavigationStore);
|
||||
YouTubeViewerDetailsFormViewModel = new YouTubeViewerDetailsFormViewModel(submitCommand, cancelCommand)
|
||||
{
|
||||
UserName = youTubeViewer.Username,
|
||||
IsSubScribed = youTubeViewer.IsSubscribed,
|
||||
IsMember = youTubeViewer.IsMember
|
||||
};
|
||||
}
|
||||
}
|
||||
38
YouTubeViewers.WPF/ViewModels/MainViewModel.cs
Normal file
38
YouTubeViewers.WPF/ViewModels/MainViewModel.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
|
||||
namespace YouTubeViewers.WPF.ViewModels
|
||||
{
|
||||
public class MainViewModel : ViewModelBase
|
||||
{
|
||||
private readonly ModalNavigationStore _modalNavigationStore;
|
||||
|
||||
public ViewModelBase CurrentModalViewModel => _modalNavigationStore.CurrentViewModel;
|
||||
public bool IsModalOpen => _modalNavigationStore.IsOpen;
|
||||
public YouTubeViewersViewModel YouTubeViewersViewModel { get; }
|
||||
|
||||
public MainViewModel(ModalNavigationStore modalNavigationStore, YouTubeViewersViewModel youTubeViewersViewModel)
|
||||
{
|
||||
_modalNavigationStore = modalNavigationStore;
|
||||
YouTubeViewersViewModel = youTubeViewersViewModel;
|
||||
|
||||
_modalNavigationStore.CurrentViewModelChanged += ModalNavigationStore_CurrenyViewModelChanged;
|
||||
}
|
||||
|
||||
protected override void Dispose()
|
||||
{
|
||||
_modalNavigationStore.CurrentViewModelChanged -= ModalNavigationStore_CurrenyViewModelChanged;
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
private void ModalNavigationStore_CurrenyViewModelChanged()
|
||||
{
|
||||
OnPropertyChanged(nameof(CurrentModalViewModel));
|
||||
OnPropertyChanged(nameof(IsModalOpen));
|
||||
}
|
||||
}
|
||||
}
|
||||
22
YouTubeViewers.WPF/ViewModels/ViewModelBase.cs
Normal file
22
YouTubeViewers.WPF/ViewModels/ViewModelBase.cs
Normal file
@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace YouTubeViewers.WPF.ViewModels
|
||||
{
|
||||
public class ViewModelBase : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged(string propertyName = null)
|
||||
{
|
||||
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
protected virtual void Dispose() { }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace YouTubeViewers.WPF.ViewModels;
|
||||
|
||||
public class YouTubeViewerDetailsFormViewModel : ViewModelBase
|
||||
{
|
||||
private string _userName;
|
||||
|
||||
public string UserName
|
||||
{
|
||||
get { return _userName; }
|
||||
set
|
||||
{
|
||||
_userName = value;
|
||||
OnPropertyChanged(nameof(UserName));
|
||||
OnPropertyChanged(nameof(CanSubmit));
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isSubScribed;
|
||||
|
||||
public bool IsSubScribed
|
||||
{
|
||||
get { return _isSubScribed; }
|
||||
set
|
||||
{
|
||||
_isSubScribed = value;
|
||||
OnPropertyChanged(nameof(IsSubScribed));
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isMember;
|
||||
|
||||
|
||||
public bool IsMember
|
||||
{
|
||||
get { return _isMember; }
|
||||
set
|
||||
{
|
||||
_isMember = value;
|
||||
OnPropertyChanged(nameof(IsMember));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region IsSubmitting
|
||||
|
||||
private bool _IsSubmitting;
|
||||
public bool IsSubmitting
|
||||
{
|
||||
get { return _IsSubmitting; }
|
||||
set { _IsSubmitting = value; OnPropertyChanged(nameof(IsSubmitting)); }
|
||||
}
|
||||
|
||||
#endregion IsSubmitting
|
||||
|
||||
public bool CanSubmit => !string.IsNullOrEmpty(UserName);
|
||||
public ICommand SubmitCommand { get; }
|
||||
public ICommand CancelCommand { get; }
|
||||
public YouTubeViewerDetailsFormViewModel(ICommand submitCommand, ICommand cancelCommand)
|
||||
{
|
||||
SubmitCommand = submitCommand;
|
||||
CancelCommand = cancelCommand;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
|
||||
namespace YouTubeViewers.WPF.ViewModels
|
||||
{
|
||||
public class YouTubeViewersDetailsViewModel : ViewModelBase
|
||||
{
|
||||
private readonly SelectedYouTubeViewerStore _selectedYouTubeViewerStore;
|
||||
private YouTubeViewer SelectedYouTubeViewer => _selectedYouTubeViewerStore.SelectedYouTubeViewer;
|
||||
|
||||
public bool HasSelectedYouTubeViewer => SelectedYouTubeViewer != null;
|
||||
public string UserName => SelectedYouTubeViewer?.Username ?? "Unknown";
|
||||
public string IsSubScribedDisplay => (SelectedYouTubeViewer?.IsSubscribed ?? false) ? "Yes" : "No";
|
||||
public string IsMemberDisplay => (SelectedYouTubeViewer?.IsMember ?? false) ? "Yes" : "No";
|
||||
|
||||
public YouTubeViewersDetailsViewModel(SelectedYouTubeViewerStore selectedYouTubeViewerStore)
|
||||
{
|
||||
_selectedYouTubeViewerStore = selectedYouTubeViewerStore;
|
||||
|
||||
_selectedYouTubeViewerStore.SelectedYouTubeViewerChanged += SelectedYouTubeViewerStore_SelectedYouTubeViewerChanged;
|
||||
}
|
||||
|
||||
protected override void Dispose()
|
||||
{
|
||||
_selectedYouTubeViewerStore.SelectedYouTubeViewerChanged -= SelectedYouTubeViewerStore_SelectedYouTubeViewerChanged;
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
private void SelectedYouTubeViewerStore_SelectedYouTubeViewerChanged()
|
||||
{
|
||||
OnPropertyChanged(nameof(HasSelectedYouTubeViewer));
|
||||
OnPropertyChanged(nameof(UserName));
|
||||
OnPropertyChanged(nameof(IsSubScribedDisplay));
|
||||
OnPropertyChanged(nameof(IsMemberDisplay));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using YouTubeViewers.WPF.Commands;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
|
||||
namespace YouTubeViewers.WPF.ViewModels
|
||||
{
|
||||
public class YouTubeViewersListingItemViewModel : ViewModelBase
|
||||
{
|
||||
//private YouTubeViewer _youTubeViewer;
|
||||
//private YouTubeViewersStore _youTubeViewersStore;
|
||||
//private ModalNavigationStore _modalNavigationStore;
|
||||
|
||||
public YouTubeViewer YouTubeViewer { get; private set; }
|
||||
|
||||
public string UserName => YouTubeViewer.Username;
|
||||
|
||||
public ICommand EditCommand { get; }
|
||||
public ICommand DeleteCommand { get; }
|
||||
|
||||
public YouTubeViewersListingItemViewModel(YouTubeViewer youTubeViewer, YouTubeViewersStore youTubeViewersStore, ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
YouTubeViewer = youTubeViewer;
|
||||
|
||||
EditCommand = new OpenEditYouTubeViewerCommand(this, youTubeViewersStore, modalNavigationStore);
|
||||
DeleteCommand = new DeleteYouTubeViewerCommand(this, youTubeViewersStore);
|
||||
}
|
||||
|
||||
public void Update(YouTubeViewer youTubeViewer)
|
||||
{
|
||||
YouTubeViewer = youTubeViewer;
|
||||
OnPropertyChanged(nameof(UserName));
|
||||
}
|
||||
}
|
||||
}
|
||||
111
YouTubeViewers.WPF/ViewModels/YouTubeViewersListingViewModel.cs
Normal file
111
YouTubeViewers.WPF/ViewModels/YouTubeViewersListingViewModel.cs
Normal file
@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using YouTubeViewers.WPF.Commands;
|
||||
using YouTubeViewers.Domain.Models;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
|
||||
namespace YouTubeViewers.WPF.ViewModels
|
||||
{
|
||||
public class YouTubeViewersListingViewModel : ViewModelBase
|
||||
{
|
||||
private readonly ObservableCollection<YouTubeViewersListingItemViewModel> _youtubeViewersListingItemViewModels;
|
||||
private readonly YouTubeViewersStore _youTubeViewersStore;
|
||||
private readonly SelectedYouTubeViewerStore _selectedYouTubeViewerStore;
|
||||
private readonly ModalNavigationStore _modalNavigationStore;
|
||||
|
||||
public IEnumerable<YouTubeViewersListingItemViewModel> YouTubeViewersListingItemViewModels => _youtubeViewersListingItemViewModels;
|
||||
|
||||
private YouTubeViewersListingItemViewModel _selectedYouTubeViewerListingItemViewModel;
|
||||
|
||||
public YouTubeViewersListingItemViewModel SelectedYouTubeViewerListingItemViewModel
|
||||
{
|
||||
get { return _selectedYouTubeViewerListingItemViewModel; }
|
||||
set
|
||||
{
|
||||
_selectedYouTubeViewerListingItemViewModel = value;
|
||||
OnPropertyChanged(nameof(SelectedYouTubeViewerListingItemViewModel));
|
||||
_selectedYouTubeViewerStore.SelectedYouTubeViewer = _selectedYouTubeViewerListingItemViewModel?.YouTubeViewer;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public YouTubeViewersListingViewModel(
|
||||
YouTubeViewersStore youTubeViewersStore,
|
||||
SelectedYouTubeViewerStore selectedYouTubeViewerStore,
|
||||
ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
_youTubeViewersStore = youTubeViewersStore;
|
||||
_selectedYouTubeViewerStore = selectedYouTubeViewerStore;
|
||||
_modalNavigationStore = modalNavigationStore;
|
||||
_youtubeViewersListingItemViewModels = new ObservableCollection<YouTubeViewersListingItemViewModel>();
|
||||
|
||||
|
||||
_youTubeViewersStore.YouTubeViewersLoaded += _youTubeViewersStore_YouTubeViewersLoaded;
|
||||
_youTubeViewersStore.YouTubeViewerAdded += YouTubeViewersStore_YouTubeViewerAdded;
|
||||
_youTubeViewersStore.YouTubeViewerUpdated += YouTubeViewersStore_YouTubeViewerUpdated;
|
||||
_youTubeViewersStore.YouTubeViewerDeleted += YouTubeViewersStore_YouTubeViewerDeleted;
|
||||
}
|
||||
|
||||
|
||||
private void _youTubeViewersStore_YouTubeViewersLoaded()
|
||||
{
|
||||
_youtubeViewersListingItemViewModels.Clear();
|
||||
foreach (YouTubeViewer youTubeViewer in _youTubeViewersStore.YouTubeViewers)
|
||||
{
|
||||
AddYouTubeViewer(youTubeViewer);
|
||||
}
|
||||
}
|
||||
|
||||
private void YouTubeViewersStore_YouTubeViewerUpdated(YouTubeViewer youTubeViewer)
|
||||
{
|
||||
YouTubeViewersListingItemViewModel youTubeViewerViewModel =
|
||||
_youtubeViewersListingItemViewModels.FirstOrDefault(x => x.YouTubeViewer.Id == youTubeViewer.Id);
|
||||
|
||||
if (youTubeViewerViewModel != null)
|
||||
{
|
||||
youTubeViewerViewModel.Update(youTubeViewer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected override void Dispose()
|
||||
{
|
||||
_youTubeViewersStore.YouTubeViewersLoaded -= _youTubeViewersStore_YouTubeViewersLoaded;
|
||||
_youTubeViewersStore.YouTubeViewerAdded -= YouTubeViewersStore_YouTubeViewerAdded;
|
||||
_youTubeViewersStore.YouTubeViewerUpdated -= YouTubeViewersStore_YouTubeViewerUpdated;
|
||||
_youTubeViewersStore.YouTubeViewerDeleted -= YouTubeViewersStore_YouTubeViewerDeleted;
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
private void YouTubeViewersStore_YouTubeViewerAdded(YouTubeViewer youTubeViewer)
|
||||
{
|
||||
AddYouTubeViewer(youTubeViewer);
|
||||
}
|
||||
|
||||
private void AddYouTubeViewer(YouTubeViewer youTubeViewer)
|
||||
{
|
||||
YouTubeViewersListingItemViewModel itemViewModel =
|
||||
new YouTubeViewersListingItemViewModel(youTubeViewer, _youTubeViewersStore, _modalNavigationStore);
|
||||
_youtubeViewersListingItemViewModels.Add(itemViewModel);
|
||||
}
|
||||
|
||||
private void YouTubeViewersStore_YouTubeViewerDeleted(Guid id)
|
||||
{
|
||||
YouTubeViewersListingItemViewModel itemViewModel = _youtubeViewersListingItemViewModels.FirstOrDefault(y => y.YouTubeViewer?.Id == id);
|
||||
|
||||
if (itemViewModel != null)
|
||||
{
|
||||
_youtubeViewersListingItemViewModels.Remove(itemViewModel);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
55
YouTubeViewers.WPF/ViewModels/YouTubeViewersViewModel.cs
Normal file
55
YouTubeViewers.WPF/ViewModels/YouTubeViewersViewModel.cs
Normal file
@ -0,0 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using YouTubeViewers.WPF.Commands;
|
||||
using YouTubeViewers.WPF.Stores;
|
||||
|
||||
namespace YouTubeViewers.WPF.ViewModels
|
||||
{
|
||||
public class YouTubeViewersViewModel : ViewModelBase
|
||||
{
|
||||
public YouTubeViewersListingViewModel YouTubeViewersListingViewModel { get; }
|
||||
public YouTubeViewersDetailsViewModel YouTubeViewersDetailsViewModel { get; }
|
||||
|
||||
|
||||
private bool _IsLoading;
|
||||
public bool IsLoading
|
||||
{
|
||||
get
|
||||
{
|
||||
return _IsLoading;
|
||||
}
|
||||
set
|
||||
{
|
||||
_IsLoading = value;
|
||||
OnPropertyChanged(nameof(IsLoading));
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand LoadYouTubeViewersCommand { get; }
|
||||
public ICommand AddYouTubeViewersCommand { get; }
|
||||
public YouTubeViewersViewModel(YouTubeViewersStore youTubeViewersStore, SelectedYouTubeViewerStore _selectedYouTubeViewerStore, ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
|
||||
YouTubeViewersListingViewModel = new YouTubeViewersListingViewModel(youTubeViewersStore, _selectedYouTubeViewerStore, modalNavigationStore);
|
||||
YouTubeViewersDetailsViewModel = new YouTubeViewersDetailsViewModel(_selectedYouTubeViewerStore);
|
||||
LoadYouTubeViewersCommand = new LoadYouTubeViewersCommand(this,youTubeViewersStore);
|
||||
AddYouTubeViewersCommand = new OpenAddYouTubeViewerCommand(youTubeViewersStore, modalNavigationStore);
|
||||
}
|
||||
|
||||
public static YouTubeViewersViewModel LoadViewModel(
|
||||
YouTubeViewersStore youTubeViewersStore,
|
||||
SelectedYouTubeViewerStore selectedYouTubeViewerStore,
|
||||
ModalNavigationStore modalNavigationStore)
|
||||
{
|
||||
YouTubeViewersViewModel viewModel = new YouTubeViewersViewModel(youTubeViewersStore, selectedYouTubeViewerStore, modalNavigationStore);
|
||||
|
||||
viewModel.LoadYouTubeViewersCommand.Execute(null);
|
||||
|
||||
return viewModel;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
YouTubeViewers.WPF/Views/AddYouTubeViewerView.xaml
Normal file
26
YouTubeViewers.WPF/Views/AddYouTubeViewerView.xaml
Normal file
@ -0,0 +1,26 @@
|
||||
<UserControl x:Class="YouTubeViewers.WPF.Views.AddYouTubeViewerView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:YouTubeViewers.WPF.Views"
|
||||
xmlns:components="clr-namespace:YouTubeViewers.WPF.Components"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Style="{StaticResource PageHeader}"
|
||||
Text="Add YouTube Viewers" />
|
||||
|
||||
<components:YouTubeViewerDetailsForm Grid.Row="1" Margin="0 30 0 0 " DataContext="{Binding YouTubeViewerDetailsFormViewModel}"/>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
|
||||
28
YouTubeViewers.WPF/Views/AddYouTubeViewerView.xaml.cs
Normal file
28
YouTubeViewers.WPF/Views/AddYouTubeViewerView.xaml.cs
Normal file
@ -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 YouTubeViewers.WPF.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for AddYouTubeViewerView.xaml
|
||||
/// </summary>
|
||||
public partial class AddYouTubeViewerView : UserControl
|
||||
{
|
||||
public AddYouTubeViewerView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
24
YouTubeViewers.WPF/Views/EditYouTubeViewerView.xaml
Normal file
24
YouTubeViewers.WPF/Views/EditYouTubeViewerView.xaml
Normal file
@ -0,0 +1,24 @@
|
||||
<UserControl x:Class="YouTubeViewers.WPF.Views.EditYouTubeViewerView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:YouTubeViewers.WPF.Views"
|
||||
xmlns:components="clr-namespace:YouTubeViewers.WPF.Components"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
Style="{StaticResource PageHeader}"
|
||||
Text="Edit YouTube Viewers" />
|
||||
|
||||
<components:YouTubeViewerDetailsForm Grid.Row="1" Margin="0 30 0 0 " DataContext="{Binding YouTubeViewerDetailsFormViewModel}"/>
|
||||
|
||||
</Grid>
|
||||
</UserControl>
|
||||
28
YouTubeViewers.WPF/Views/EditYouTubeViewerView.xaml.cs
Normal file
28
YouTubeViewers.WPF/Views/EditYouTubeViewerView.xaml.cs
Normal file
@ -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 YouTubeViewers.WPF.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for EditYouTubeViewerView.xaml
|
||||
/// </summary>
|
||||
public partial class EditYouTubeViewerView : UserControl
|
||||
{
|
||||
public EditYouTubeViewerView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
59
YouTubeViewers.WPF/Views/YouTubeViewersView.xaml
Normal file
59
YouTubeViewers.WPF/Views/YouTubeViewersView.xaml
Normal file
@ -0,0 +1,59 @@
|
||||
<UserControl x:Class="YouTubeViewers.WPF.Views.YouTubeViewersView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:YouTubeViewers.WPF.Views"
|
||||
xmlns:components="clr-namespace:YouTubeViewers.WPF.Components"
|
||||
xmlns:custom="clr-namespace:LoadingSpinnerControl;assembly=LoadingSpinnerControl"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<Grid>
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<StackPanel.Style>
|
||||
<Style TargetType="StackPanel">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsLoading}" Value="true">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</StackPanel.Style>
|
||||
<custom:LoadingSpinner Diameter="100" IsLoading="True" Thickness="3"/>
|
||||
<TextBlock Margin="0 10 0 0" Text="Loading YouTube Viewers..." TextAlignment="Center" />
|
||||
</StackPanel>
|
||||
<Grid>
|
||||
<Grid.Style>
|
||||
<Style TargetType="Grid">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsLoading}" Value="false">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Grid.Style>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Style="{StaticResource PageHeader}" Text="YouTube Viewers" />
|
||||
<Button Grid.Column="1" Content="Add" FontSize="16" Command="{Binding AddYouTubeViewersCommand}"/>
|
||||
</Grid>
|
||||
<Grid Grid.Row="1" Margin="0 20 0 0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="2*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<components:YouTubeViewersListing Grid.Column="0" DataContext="{Binding YouTubeViewersListingViewModel}"/>
|
||||
<components:YouTubeViewersDetails Grid.Column="1" Margin="20 0 0 0" DataContext="{Binding YouTubeViewersDetailsViewModel}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
28
YouTubeViewers.WPF/Views/YouTubeViewersView.xaml.cs
Normal file
28
YouTubeViewers.WPF/Views/YouTubeViewersView.xaml.cs
Normal file
@ -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 YouTubeViewers.WPF.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for YouTubeViewersView.xaml
|
||||
/// </summary>
|
||||
public partial class YouTubeViewersView : UserControl
|
||||
{
|
||||
public YouTubeViewersView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
21
YouTubeViewers.WPF/YouTubeViewers.WPF.csproj
Normal file
21
YouTubeViewers.WPF/YouTubeViewers.WPF.csproj
Normal file
@ -0,0 +1,21 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DropdownMenu.WPF" Version="1.0.0" />
|
||||
<PackageReference Include="LoadingSpinner.WPF" Version="1.0.0" />
|
||||
<PackageReference Include="SimpleModal.WPF" Version="1.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\YouTubeViewers.Domain\YouTubeViewers.Domain.csproj" />
|
||||
<ProjectReference Include="..\YouTubeViewers.EntityFramework\YouTubeViewers.EntityFramework.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
37
YouTubeViewers.sln
Normal file
37
YouTubeViewers.sln
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.2.32630.192
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "YouTubeViewers.WPF", "YouTubeViewers.WPF\YouTubeViewers.WPF.csproj", "{679DDC1B-2FA6-42C0-B910-A6712C0E5855}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YouTubeViewers.EntityFramework", "YouTubeViewers.EntityFramework\YouTubeViewers.EntityFramework.csproj", "{5AF69F2E-1B26-4EC0-B4BC-68E82D22A951}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YouTubeViewers.Domain", "YouTubeViewers.Domain\YouTubeViewers.Domain.csproj", "{98B6551C-821E-4F94-8596-FD51ABC486EC}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{679DDC1B-2FA6-42C0-B910-A6712C0E5855}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{679DDC1B-2FA6-42C0-B910-A6712C0E5855}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{679DDC1B-2FA6-42C0-B910-A6712C0E5855}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{679DDC1B-2FA6-42C0-B910-A6712C0E5855}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5AF69F2E-1B26-4EC0-B4BC-68E82D22A951}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5AF69F2E-1B26-4EC0-B4BC-68E82D22A951}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5AF69F2E-1B26-4EC0-B4BC-68E82D22A951}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5AF69F2E-1B26-4EC0-B4BC-68E82D22A951}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{98B6551C-821E-4F94-8596-FD51ABC486EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{98B6551C-821E-4F94-8596-FD51ABC486EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{98B6551C-821E-4F94-8596-FD51ABC486EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{98B6551C-821E-4F94-8596-FD51ABC486EC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {2C2C9C21-98B7-408C-BFA3-B942E31D21AA}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Reference in New Issue
Block a user