This commit is contained in:
Carl de Billy 2018-08-01 15:18:32 -04:00
Родитель 80322aec3d
Коммит 5e23281b05
345 изменённых файлов: 1883 добавлений и 531 удалений

33
.editorconfig Normal file
Просмотреть файл

@ -0,0 +1,33 @@
root = true
[*]
end_of_line = crlf
tab_width = 4
trim_trailing_whitespace = true
insert_final_newline = true
[*.xml]
indent_style = tab
[*.xaml]
indent_style = tab
[{*.cs, *.ts}]
indent_style = tab
[*.json]
indent_style = tab
[*.*proj]
indent_style = tab
tab_width = 2
indent_size = 2
[*.js]
indent_style = space
[*.yml]
indent_style = space
[*.md]
indent_style = space

5
.gitignore поставляемый
Просмотреть файл

@ -25,8 +25,7 @@ bld/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
**/wwwroot/playground
wwwroot
# MSTest test Results
[Tt]est[Rr]esult*/
@ -153,7 +152,7 @@ publish/
PublishScripts/
# NuGet Packages
#*.nupkg
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.

Двоичный файл не отображается.

Просмотреть файл

@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Uno.UI.Demo.AspnetShell.Models;
namespace Uno.UI.Demo.AspnetShell.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}
}

Просмотреть файл

@ -1,11 +0,0 @@
using System;
namespace Uno.UI.Demo.AspnetShell.Models
{
public class ErrorViewModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}

Просмотреть файл

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Uno.UI.Demo.AspnetShell
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}

Просмотреть файл

@ -1 +0,0 @@
<a href="Playground/index.html">Playground...</a>

Просмотреть файл

@ -1,22 +0,0 @@
@model ErrorViewModel
@{
ViewData["Title"] = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>Development environment should not be enabled in deployed applications</strong>, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>, and restarting the application.
</p>

Просмотреть файл

@ -1,29 +0,0 @@
@using System.Reflection
@using Microsoft.DotNet.PlatformAbstractions
@{
var version = typeof(Program)
.GetTypeInfo()
.Assembly
.GetCustomAttribute<AssemblyFileVersionAttribute>()
?.Version
?? "0.0-dev";
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"]Uno</title>
<link rel="icon" type="image/png" href="~/images/favicon16.png" sizes="16x16">
<link rel="icon" type="image/png" href="~/images/favicon24.png" sizes="24x24">
<link rel="icon" type="image/png" href="~/images/favicon32.png" sizes="32x32">
<link rel="icon" type="image/png" href="~/images/favicon48.png" sizes="48x48">
<link rel="icon" type="image/png" href="~/images/favicon256.png" sizes="256x256">
</head>
<body>
@RenderBody()
@RenderSection("Scripts", required: false)
</body>
</html>

Просмотреть файл

@ -1,18 +0,0 @@
<environment include="Development">
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
</environment>
<environment exclude="Development">
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"
asp-fallback-src="~/lib/jquery-validation/dist/jquery.validate.min.js"
asp-fallback-test="window.jQuery && window.jQuery.validator"
crossorigin="anonymous"
integrity="sha384-Fnqn3nxp3506LP/7Y3j/25BlWeA3PXTyT1l78LjECcPaKCV12TsZP7yyMxOe/G/k">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/jquery.validation.unobtrusive/3.2.6/jquery.validate.unobtrusive.min.js"
asp-fallback-src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"
asp-fallback-test="window.jQuery && window.jQuery.validator && window.jQuery.validator.unobtrusive"
crossorigin="anonymous"
integrity="sha384-JrXK+k53HACyavUKOsL+NkmSesD2P+73eDMrbTtTk0h4RmOF8hF8apPlkp26JlyH">
</script>
</environment>

Просмотреть файл

@ -1,3 +0,0 @@
@using Uno.UI.Demo.AspnetShell
@using Uno.UI.Demo.AspnetShell.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

Просмотреть файл

@ -1,3 +0,0 @@
@{
Layout = "_Layout";
}

Двоичные данные
Uno.UI.Demo.AspnetShell/wwwroot/favicon.ico

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Просмотреть файл

@ -1 +0,0 @@
google-site-verification: googlebbe0bf0f35d3c279.html

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 477 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 802 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 16 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.9 KiB

Просмотреть файл

@ -1,113 +0,0 @@
<UserControl x:Class="Uno.UI.Demo.Samples.Animations"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Uno.UI.Demo.Samples"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="">
<ScrollViewer>
<StackPanel Style="{StaticResource SamplePanelStyle}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="AnimationTests">
<VisualState x:Name="Animated">
<Storyboard>
<!-- Animation 1 -->
<DoubleAnimation Storyboard.TargetProperty="Angle"
Storyboard.TargetName="RotateTransform1"
From="0"
To="360"
Duration="0:0:3" />
<DoubleAnimation Storyboard.TargetProperty="Opacity"
Storyboard.TargetName="Rectangle1"
To="0"
Duration="0:0:2" />
<!-- Animation 2 -->
<DoubleAnimation Storyboard.TargetProperty="ScaleX"
Storyboard.TargetName="ScaleTransform1"
To="0.5"
Duration="0:0:2">
<DoubleAnimation.EasingFunction>
<BounceEase Bounces="2"
Bounciness="3" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetProperty="ScaleY"
Storyboard.TargetName="ScaleTransform1"
To="0.5"
Duration="0:0:2">
<DoubleAnimation.EasingFunction>
<BounceEase Bounces="2"
Bounciness="3" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<!-- Animation 3 -->
<DoubleAnimation Storyboard.TargetProperty="Y"
Storyboard.TargetName="TranslateTransform1"
From="0"
To="150"
Duration="0:0:2">
<DoubleAnimation.EasingFunction>
<BounceEase Bounces="2"
Bounciness="3" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
<DoubleAnimation Storyboard.TargetProperty="X"
Storyboard.TargetName="TranslateTransform2"
From="0"
To="150"
Duration="0:0:2">
<DoubleAnimation.EasingFunction>
<CubicEase EasingMode="EaseInOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</VisualState>
<VisualState x:Name="NotAnimated" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock Style="{StaticResource SampleSectionTextBlockStyle}"
TextWrapping="Wrap"
Text="Animations using VisualStates, DoubleAnimations, EasingFunctions and RenderTransforms" />
<Button Content="Click me!"
Click="Button_Click" />
<Rectangle Fill="{StaticResource Color13Brush}"
Width="100"
Height="100"
x:Name="Rectangle1"
Opacity="1">
<Rectangle.RenderTransform>
<RotateTransform CenterX="50"
CenterY="50"
x:Name="RotateTransform1" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{StaticResource Color16Brush}"
Width="100"
Height="100">
<Rectangle.RenderTransform>
<ScaleTransform CenterX="50"
CenterY="50"
x:Name="ScaleTransform1" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{StaticResource Color15Brush}"
Width="100"
Height="100">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="TranslateTransform1" />
</Rectangle.RenderTransform>
</Rectangle>
<Rectangle Fill="{StaticResource Color14Brush}"
Width="100"
Height="100">
<Rectangle.RenderTransform>
<TranslateTransform x:Name="TranslateTransform2" />
</Rectangle.RenderTransform>
</Rectangle>
</StackPanel>
</ScrollViewer>
</UserControl>

Просмотреть файл

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>6279c845-92f8-4333-ab99-3d213163593c</ProjectGuid>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
<PropertyGroup />
<Import Project="Uno.UI.Demo.Shared.projitems" Label="Shared" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.1" />
</ItemGroup>
</Project>

Просмотреть файл

@ -1,49 +0,0 @@
var Uno;
(function (Uno) {
var UI;
(function (UI) {
var Demo;
(function (Demo) {
var Analytics = /** @class */ (function () {
function Analytics() {
}
Analytics.reportPageView = function (screenName, appName) {
if (appName === void 0) { appName = "Uno.UI.Demo.Playground"; }
if (Analytics.init(screenName, appName)) {
return "ok";
}
var gtag = window.gtag;
if (gtag) {
gtag("event", "screen_view", {
screen_name: screenName,
app_name: appName
});
}
else {
console.error("Google Analytics not present, can't report page view for " + screenName + ".");
}
return "ok";
};
Analytics.init = function (screenName, appName) {
if (Analytics.isLoaded) {
return false;
}
var script = "\n\twindow.dataLayer = window.dataLayer || [];\n\tfunction gtag() { dataLayer.push(arguments); }\n\tgtag('js', new Date());\n\tgtag('config', 'UA-26688675-3');\n\tgtag(\"event\", \"screen_view\", {screen_name: \"" + screenName + "\", app_name: \"" + appName + "\"});";
var script1 = document.createElement("script");
script1.type = "text/javascript";
script1.src = "https://www.googletagmanager.com/gtag/js?id=UA-26688675-3";
document.body.appendChild(script1);
var script2 = document.createElement("script");
script2.type = "text/javascript";
script2.innerText = script;
document.body.appendChild(script2);
Analytics.isLoaded = true;
return true;
};
Analytics.isLoaded = false;
return Analytics;
}());
Demo.Analytics = Analytics;
})(Demo = UI.Demo || (UI.Demo = {}));
})(UI = Uno.UI || (Uno.UI = {}));
})(Uno || (Uno = {}));

15
gitversion.yml Normal file
Просмотреть файл

@ -0,0 +1,15 @@
assembly-versioning-scheme: MajorMinorPatch
mode: ContinuousDeployment
next-version: 1.3.0
continuous-delivery-fallback-tag: ""
branches:
master:
tag: dev
stable:
tag:
dev/.*?/(.*?):
tag: dev.{BranchName}
projects/(.*?):
tag: proj-{BranchName}
ignore:
sha: []

Просмотреть файл

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<activePackageSource>
<add key="All" value="(Aggregate source)" />
</activePackageSource>
<packageSources>
<add key="LocalCache" value=".\NugetPackages" />
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="Microsoft and .NET" value="https://www.nuget.org/api/v2/curated-feeds/microsoftdotnet/" />
</packageSources>
<disabledPackageSources>
<add key="Microsoft and .NET" value="true" />
</disabledPackageSources>
</configuration>

19
src/Build/Build.csproj Normal file
Просмотреть файл

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GetVersion>false</GetVersion>
<UpdateAssemblyInfo>false</UpdateAssemblyInfo>
</PropertyGroup>
<ItemGroup>
<None Include="..\.vsts-ci.yml" Link=".vsts-ci.yml" />
<None Include="build.proj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="GitVersionTask" Version="3.6.5" />
<PackageReference Include="MSBuildTasks" Version="1.5.0.235" />
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1 @@
Uno Gallery

34
src/Build/build.proj Normal file
Просмотреть файл

@ -0,0 +1,34 @@
<Project DefaultTargets="UpdateVersion">
<Import Project="obj\Build.csproj.nuget.g.props" Condition="Exists('obj\Build.csproj.nuget.g.props')" />
<Import Project="obj\Build.csproj.nuget.g.targets" Condition="Exists('obj\Build.csproj.nuget.g.targets')" />
<Target Name="UpdateVersion" DependsOnTargets="GetVersion">
<Message Text="Updating versions" />
<XmlUpdate XmlFileName="..\Uno.Playground.iOS\Info.plist"
XPath="//plist/dict/key[text() = 'CFBundleShortVersionString']/following-sibling::string[1]"
Value="$(GITVERSION_MAJOR).$(GITVERSION_MINOR)" />
<XmlUpdate XmlFileName="..\Uno.Playground.iOS\Info.plist"
XPath="//plist/dict/key[text() = 'CFBundleVersion']/following-sibling::string[1]"
Value="$(GITVERSION_COMMITSSINCEVERSIONSOURCE)" />
<XmlUpdate
XmlFileName="..\Uno.Playground.Droid\Properties\AndroidManifest.xml"
XPath="/manifest/@android:versionCode"
Value="$(GITVERSION_COMMITSSINCEVERSIONSOURCE)"
Namespace="http://schemas.android.com/apk/res/android"
Prefix="android" />
<XmlUpdate
XmlFileName="..\Uno.Playground.UWP\package.appxmanifest"
XPath="/x:Package/x:Identity/@Version"
Value="$(GITVERSION_MAJOR).$(GITVERSION_MINOR).$(GITVERSION_COMMITSSINCEVERSIONSOURCE).0"
Namespace="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
Prefix="x"/>
<Message Text="Assm: Ver $(GITVERSION_MAJOR).$(GITVERSION_MINOR).$(GITVERSION_COMMITSSINCEVERSIONSOURCE)" />
</Target>
</Project>

Просмотреть файл

@ -0,0 +1,8 @@
namespace Uno.UI.Demo.Api
{
internal static class Constants
{
internal const string SamplesTableName = "Samples";
internal const string DefaultCategoryIdForSaving = "default";
}
}

Просмотреть файл

@ -0,0 +1,26 @@
using System.Net.Http;
using System.ServiceModel.Channels;
using System.Web;
namespace Uno.UI.Demo.AspnetShell.Helpers
{
public static class HttpRequestMessageExtensions
{
public static string GetClientIp(this HttpRequestMessage request)
{
if (request.Properties.ContainsKey("MS_HttpContext"))
{
return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
}
if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
{
RemoteEndpointMessageProperty prop;
prop = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name];
return prop.Address;
}
return null;
}
}
}

Просмотреть файл

@ -0,0 +1,39 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.WindowsAzure.Storage.Table;
namespace Uno.UI.Demo.Api.Helpers
{
public static class TableQueryExtensions
{
public static TableQuery<T> SelectColumn<T>(
this TableQuery<T> tableQuery,
string column)
where T : ITableEntity, new()
{
if (tableQuery.SelectColumns == null)
{
tableQuery.SelectColumns = new List<string>();
}
tableQuery.SelectColumns.Add(column);
return tableQuery;
}
public static Task<TableQuerySegment<T>> ExecuteQuery<T>(
this CloudTable cloudTable,
TableQuery<T> query,
CancellationToken ct)
where T : ITableEntity, new()
{
return cloudTable.ExecuteQuerySegmentedAsync(
query,
token: null,
requestOptions: null,
operationContext: null,
cancellationToken: ct);
}
}
}

Просмотреть файл

@ -0,0 +1,52 @@
using Microsoft.WindowsAzure.Storage.Table;
namespace Uno.UI.Demo.Api.Models
{
public class Sample : TableEntity
{
public Sample()
{
PartitionKey = nameof(Sample);
}
public Sample(string id) : this()
{
RowKey = id;
ETag = "*";
}
[IgnoreProperty]
public string Id => RowKey;
public string Category { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string Xaml { get; set; }
public string Data { get; set; }
[IgnoreProperty]
public string[] ParsedKeywords
{
get => Keywords?.Split(';') ?? new string[] {};
set => Keywords = value == null ? "" : string.Join(";", value);
}
public string Keywords { get; set; }
public string IpAddress { get; set; }
public string App { get; set; }
public string UserAgent { get; set; }
public long ListingOrder { get; set; } = 0;
public string PathData { get; set; }
public string AccentPathData { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,29 @@
using Microsoft.WindowsAzure.Storage.Table;
namespace Uno.UI.Demo.Api.Models
{
public class SampleCategory : TableEntity
{
public SampleCategory()
{
PartitionKey = nameof(SampleCategory);
}
public SampleCategory(string id) : this()
{
RowKey = id;
ETag = "*";
}
[IgnoreProperty]
public string Id => RowKey;
public string Title { get; set; }
public long ListingOrder { get; set; } = 0;
public string PathData { get; set; }
public string AccentPathData { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,64 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace Uno.UI.Demo.Api.Models
{
public class SampleCategoryViewModel
{
private readonly SampleCategory _category;
public SampleCategoryViewModel(SampleCategory category, IEnumerable<Sample> samples)
{
_category = category;
Samples = samples
.Where(s => s.Category.Equals(category.Id))
.Select(s => new SampleViewModel(s)).ToArray();
}
public string CategoryId => _category.Id;
public string Title => _category.Title;
public string DefaultIconPath => _category.PathData;
public string DefaultIconAccentPath => _category.AccentPathData;
public SampleViewModel[] Samples { get; }
[IgnoreDataMember]
public int SamplesHash
{
get
{
var sum = 0;
foreach (var s in Samples)
{
unchecked
{
sum += GetEtagHash(s.Etag);
}
}
return sum;
}
}
private static int GetEtagHash(string s)
{
unchecked
{
var r = 0;
foreach (var c in s)
{
r += c;
}
return r;
}
}
}
}

Просмотреть файл

@ -0,0 +1,24 @@
namespace Uno.UI.Demo.Api.Models
{
public class SampleDetailViewModel
{
private readonly Sample _sample;
public SampleDetailViewModel(Sample sample)
{
_sample = sample;
}
public string Id => _sample.Id;
public string Title => _sample.Title ?? "";
public string Description => _sample.Description ?? "";
public string Category => _sample.Category;
public string Xaml => _sample.Xaml ?? "";
public string Data => _sample.Data ?? "";
}
}

Просмотреть файл

@ -0,0 +1,13 @@
namespace Uno.UI.Demo.Api.Models
{
public class SampleSaveRequest
{
public string App { get; set; }
public string Category { get; set; }
public string Title { get; set; }
public string Xaml { get; set; }
public string Data { get; set; }
public string PathData { get; set; }
public string AccentPathData { get; set; }
}
}

Просмотреть файл

@ -0,0 +1,29 @@
using System.Runtime.Serialization;
namespace Uno.UI.Demo.Api.Models
{
public partial class SampleViewModel
{
private readonly Sample _sample;
public SampleViewModel(Sample sample)
{
_sample = sample;
}
public string Id => _sample.Id;
public string Title => _sample.Title ?? "(no title)";
public string Description => _sample.Description ?? "";
public string[] Keywords => _sample.ParsedKeywords ?? new string[] { };
public string IconPath => _sample.PathData;
public string IconAccentPath => _sample.AccentPathData;
[IgnoreDataMember]
public string Etag => _sample.ETag;
}
}

Просмотреть файл

@ -0,0 +1,41 @@
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Table.Queryable;
using Uno.UI.Demo.Api.Helpers;
using Uno.UI.Demo.Api.Models;
namespace Uno.UI.Demo.Api
{
public static class SampleGet
{
[FunctionName("SampleGet")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "samples/{id}")]
HttpRequestMessage req,
[Table(Constants.SamplesTableName)] CloudTable table,
TraceWriter log,
string id,
CancellationToken ct)
{
var sampleQuery = table
.CreateQuery<Sample>()
.Where(smpl => smpl.PartitionKey.Equals(nameof(Sample)) && smpl.RowKey.Equals(id))
.AsTableQuery();
var queryResult = await table.ExecuteQuery(sampleQuery, ct);
var sample = queryResult.Select(s => new SampleDetailViewModel(s)).FirstOrDefault();
return sample == null
? req.CreateErrorResponse(HttpStatusCode.NotFound, "Sample not found")
: req.CreateResponse(HttpStatusCode.OK, sample);
}
}
}

Просмотреть файл

@ -0,0 +1,80 @@
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.WindowsAzure.Storage.Table;
using Newtonsoft.Json;
using Uno.UI.Demo.Api.Models;
using Uno.UI.Demo.AspnetShell.Helpers;
namespace Uno.UI.Demo.Api
{
public static class SamplePost
{
[FunctionName("SamplePost")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "samples")]
HttpRequestMessage req,
[Table(Constants.SamplesTableName)] CloudTable table,
TraceWriter log,
CancellationToken ct)
{
var saveRequest =
JsonConvert.DeserializeObject<SampleSaveRequest>(await req.Content.ReadAsStringAsync());
if (saveRequest == null)
{
return req.CreateErrorResponse(HttpStatusCode.BadRequest, "Request payload required.");
}
var id = Guid.NewGuid().ToString("N").Substring(24); // 8 characters is enough
if (saveRequest.Xaml == null || saveRequest.Xaml.Length < 5)
{
return req.CreateErrorResponse(HttpStatusCode.BadRequest, "Xaml required.");
}
if (saveRequest.Xaml.Length > 512 * 1024)
{
return req.CreateErrorResponse(HttpStatusCode.RequestEntityTooLarge, "Xaml too big.");
}
if (saveRequest.Data != null && saveRequest.Data.Length > 16 * 1024)
{
return req.CreateErrorResponse(HttpStatusCode.RequestEntityTooLarge, "Data too big.");
}
if (saveRequest.Title != null && saveRequest.Title.Length > 255)
{
return req.CreateErrorResponse(HttpStatusCode.RequestEntityTooLarge, "Title too big.");
}
if (saveRequest.App != null && saveRequest.App.Length > 255)
{
return req.CreateErrorResponse(HttpStatusCode.RequestEntityTooLarge, "App name too big.");
}
var sample = new Sample(id)
{
Data = saveRequest.Data,
Xaml = saveRequest.Xaml,
Category = Constants.DefaultCategoryIdForSaving,
Title = saveRequest.Title,
IpAddress = req.GetClientIp(),
UserAgent = req.Headers.UserAgent.ToString(),
App = saveRequest.App
};
var operation = new TableBatchOperation();
operation.Insert(sample);
await table.ExecuteBatchAsync(operation, null, null, ct);
return req.CreateResponse(HttpStatusCode.OK, id);
}
}
}

Просмотреть файл

@ -0,0 +1,129 @@
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Table.Queryable;
using Newtonsoft.Json;
using Uno.UI.Demo.Api.Helpers;
using Uno.UI.Demo.Api.Models;
using Uno.UI.Demo.AspnetShell.Helpers;
namespace Uno.UI.Demo.Api
{
public static class SampleSave
{
[FunctionName("SampleSave")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Admin, "put", Route = "samples/{id}")]
HttpRequestMessage req,
[Table(Constants.SamplesTableName)] CloudTable table,
string id,
TraceWriter log,
CancellationToken ct)
{
var clientIp = req.GetClientIp();
var saveRequest =
JsonConvert.DeserializeObject<SampleSaveRequest>(await req.Content.ReadAsStringAsync());
var existingQuery = table
.CreateQuery<Sample>()
.Where(smpl => smpl.PartitionKey.Equals(nameof(Sample)) && smpl.RowKey.Equals(id))
.AsTableQuery();
var existing = (await table.ExecuteQuery(existingQuery, ct)).FirstOrDefault();
var sample = existing ?? new Sample(id);
var exists = existing != null;
if (saveRequest == null)
{
return req.CreateErrorResponse(HttpStatusCode.BadRequest, "Request payload required.");
}
if (!exists && (saveRequest.Xaml == null || saveRequest.Xaml.Length < 5))
{
return req.CreateErrorResponse(HttpStatusCode.BadRequest, "Xaml required.");
}
if (saveRequest.Xaml != null && saveRequest.Xaml.Length > 512 * 1024)
{
return req.CreateErrorResponse(HttpStatusCode.RequestEntityTooLarge, "Xaml too big.");
}
if (saveRequest.Data != null && saveRequest.Data.Length > 16 * 1024)
{
return req.CreateErrorResponse(HttpStatusCode.RequestEntityTooLarge, "Data too big.");
}
if (saveRequest.Title != null && saveRequest.Title.Length > 255)
{
return req.CreateErrorResponse(HttpStatusCode.RequestEntityTooLarge, "Title too big.");
}
if (saveRequest.App != null && saveRequest.App.Length > 255)
{
return req.CreateErrorResponse(HttpStatusCode.RequestEntityTooLarge, "App name too big.");
}
if (!string.IsNullOrWhiteSpace(saveRequest.Data))
{
sample.Data = saveRequest.Data;
}
if (!string.IsNullOrWhiteSpace(saveRequest.Xaml))
{
sample.Xaml = saveRequest.Xaml;
}
if (string.IsNullOrWhiteSpace(sample.Category) || !string.IsNullOrWhiteSpace(saveRequest.Category))
{
sample.Category = saveRequest.Category ?? Constants.DefaultCategoryIdForSaving;
}
if (!string.IsNullOrWhiteSpace(saveRequest.Title))
{
sample.Title = saveRequest.Title;
}
if (string.IsNullOrWhiteSpace(sample.IpAddress))
{
sample.IpAddress = clientIp;
}
if (string.IsNullOrWhiteSpace(sample.UserAgent))
{
sample.UserAgent = req.Headers.UserAgent.ToString();
}
if (!string.IsNullOrWhiteSpace(saveRequest.App))
{
sample.App = saveRequest.App;
}
if (!string.IsNullOrWhiteSpace(saveRequest.PathData))
{
sample.PathData = saveRequest.PathData;
}
if (!string.IsNullOrWhiteSpace(saveRequest.AccentPathData))
{
sample.AccentPathData = saveRequest.AccentPathData;
}
var operation = new TableBatchOperation();
if (existing == null)
{
operation.Insert(sample);
}
else
{
operation.Merge(sample);
}
await table.ExecuteBatchAsync(operation, null, null, ct);
return req.CreateResponse(HttpStatusCode.OK, id);
}
}
}

Просмотреть файл

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.WindowsAzure.Storage.Table;
using Microsoft.WindowsAzure.Storage.Table.Queryable;
using Uno.UI.Demo.Api.Helpers;
using Uno.UI.Demo.Api.Models;
namespace Uno.UI.Demo.Api
{
public static class SamplesGet
{
[FunctionName("SamplesGet")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "samples")]
HttpRequestMessage req,
[Table(Constants.SamplesTableName)] CloudTable table,
TraceWriter log,
CancellationToken ct)
{
var categoriesQuery = table
.CreateQuery<SampleCategory>()
.Where(cat => cat.PartitionKey.Equals(nameof(SampleCategory)) && !cat.RowKey.Equals(Constants.DefaultCategoryIdForSaving))
.AsTableQuery()
.SelectColumn(nameof(SampleCategory.Title));
var categories = (await table.ExecuteQuery(categoriesQuery, ct))
.OrderBy(cat => cat.ListingOrder)
.ThenBy(cat => cat.Title)
.ThenBy(cat => cat.Id)
.ToArray();
var result = new List<SampleCategoryViewModel>(categories.Length);
var etagSb = new StringBuilder();
etagSb.Append('"');
foreach (var category in categories)
{
var samplesQuery = table
.CreateQuery<Sample>()
.Where(smpl => smpl.PartitionKey.Equals(nameof(Sample)) && smpl.Category.Equals(category.Id))
.AsTableQuery()
.SelectColumn(nameof(Sample.Category))
.SelectColumn(nameof(Sample.Title))
.SelectColumn(nameof(Sample.Description))
.SelectColumn(nameof(Sample.Keywords));
var samples = (await table.ExecuteQuery(samplesQuery, ct))
.OrderBy(cat => cat.ListingOrder)
.ThenBy(cat => cat.Title)
.ThenBy(cat => cat.Id)
.ToArray();
var categoryVm = new SampleCategoryViewModel(category, samples);
result.Add(categoryVm);
etagSb.Append(categoryVm.SamplesHash.ToString("X"));
}
etagSb.Append('"');
var etag = etagSb.ToString();
if (req.Headers.IfMatch.Any(im => im.Tag.Equals(etag, StringComparison.OrdinalIgnoreCase)))
{
return req.CreateResponse(HttpStatusCode.NotModified);
}
var response = req.CreateResponse(HttpStatusCode.OK, result.ToArray());
response.Headers.CacheControl =
new CacheControlHeaderValue
{
NoCache = false,
Private = false,
MaxAge = TimeSpan.FromHours(0.5),
MustRevalidate = false,
NoStore = false,
NoTransform = true,
MaxStale = true
};
response.Headers.ETag = new EntityTagHeaderValue(etag, false);
return response;
}
}
}

Просмотреть файл

@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.13" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Web" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
</Project>

Просмотреть файл

@ -0,0 +1,2 @@
{
}

5
src/Uno.Playground.AspnetShell/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,5 @@
wwwroot/*
!wwwroot/*.ico
!wwwroot/google*

Просмотреть файл

@ -0,0 +1,18 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
namespace Uno.UI.Demo.AspnetShell
{
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
}

Просмотреть файл

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
@ -10,15 +11,11 @@ using Microsoft.AspNetCore.Rewrite;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Table;
namespace Uno.UI.Demo.AspnetShell
{
public class Startup
{
private const string PlaygroundHost = "playground.platform.uno";
public Startup(IConfiguration configuration)
{
Configuration = configuration;
@ -29,7 +26,10 @@ namespace Uno.UI.Demo.AspnetShell
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddResponseCompression(c =>
{
c.EnableForHttps = true;
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@ -42,28 +42,23 @@ namespace Uno.UI.Demo.AspnetShell
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseExceptionHandler("/error.html");
}
app.UseResponseCompression();
// Static content
app.UseDefaultFiles();
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = CreateContentTypeProvider(),
OnPrepareResponse = ConfigureCacheControl,
});
// MVC (dynamic) content
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
OnPrepareResponse = ConfigureCacheControl
});
}
private static void ConfigureCacheControl(StaticFileResponseContext ctx)
{
if (ctx.File.Name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
if (ctx.File.Name.EndsWith(".clr", StringComparison.OrdinalIgnoreCase))
{
// Cache managed files for a year, based on this update:
// https://github.com/nventive/Uno.Wasm.Bootstrap/commit/f4859452c715c54ac40b968a303a242b0399d59a
@ -73,9 +68,14 @@ namespace Uno.UI.Demo.AspnetShell
private FileExtensionContentTypeProvider CreateContentTypeProvider()
{
var provider = new FileExtensionContentTypeProvider();
provider.Mappings[".wasm"] = "application/wasm";
provider.Mappings[".dll"] = "application/octet-stream";
var provider = new FileExtensionContentTypeProvider
{
Mappings =
{
[".wasm"] = "application/wasm",
[".clr"] = "application/octet-stream"
}
};
return provider;
}
}

Просмотреть файл

@ -1,9 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Remove="wwwroot\playground\**" />
<Content Remove="wwwroot\playground\**" />
<EmbeddedResource Remove="wwwroot\playground\**" />
<None Remove="wwwroot\playground\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.7" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.3" />
@ -13,8 +20,4 @@
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.3" />
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\playground\" />
</ItemGroup>
</Project>

Просмотреть файл

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 16 KiB

После

Ширина:  |  Высота:  |  Размер: 16 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 36 KiB

После

Ширина:  |  Высота:  |  Размер: 36 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 58 KiB

После

Ширина:  |  Высота:  |  Размер: 58 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 4.7 KiB

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 3.6 KiB

После

Ширина:  |  Высота:  |  Размер: 3.6 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 4.7 KiB

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 2.9 KiB

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 2.3 KiB

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 2.9 KiB

После

Ширина:  |  Высота:  |  Размер: 2.9 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 6.5 KiB

После

Ширина:  |  Высота:  |  Размер: 6.5 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 5.0 KiB

После

Ширина:  |  Высота:  |  Размер: 5.0 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 6.5 KiB

После

Ширина:  |  Высота:  |  Размер: 6.5 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 10 KiB

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 7.9 KiB

После

Ширина:  |  Высота:  |  Размер: 7.9 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 10 KiB

После

Ширина:  |  Высота:  |  Размер: 10 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 14 KiB

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 12 KiB

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 14 KiB

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Просмотреть файл

@ -89,7 +89,7 @@
<Version>1.22.0-dev.23</Version>
</PackageReference>
<PackageReference Include="Uno.UI">
<Version>1.29.1-aobfwasm.2834</Version>
<Version>1.30.1-aobfwasm.2873</Version>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="1.1.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Filter" Version="1.1.1" />

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 448 B

После

Ширина:  |  Высота:  |  Размер: 448 B

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 169 B

После

Ширина:  |  Высота:  |  Размер: 169 B

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 94 B

После

Ширина:  |  Высота:  |  Размер: 94 B

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 390 B

После

Ширина:  |  Высота:  |  Размер: 390 B

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 500 B

После

Ширина:  |  Высота:  |  Размер: 500 B

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше