Initial commit
Двоичные данные
2019/Technical/2019_09_23_DotnetConf2019_XamarinProductiveBeautiful.pptx
Normal file
Двоичные данные
2019/Technical/ABP.IO Open Source Web Application Framework for ASP.NET Core 3.0.pptx
Normal file
Двоичные данные
2019/Technical/Building a mobile image classifier with Custom Vision.pdf
Normal file
Двоичные данные
2019/Technical/Indexing and searching NuGet.org with Azure Functions and Search.pptx
Normal file
Двоичные данные
2019/Technical/Move your Web Forms app to .NET Core without rewriting everything.pptx
Normal file
Двоичные данные
2019/Technical/PlayFab + Azure Functions + Visual Studio Code = Crazy Awesome Games!.pptx
Normal file
Двоичные данные
2019/Technical/Publish or perish - tricks to successfully ship your .NET Core 3 app.pptx
Normal file
|
@ -0,0 +1,9 @@
|
|||
These are the session decks that our .NET Conf 2019 speakers presented. The demo code for the keynote is also available in the demo folder.
|
||||
|
||||
A HUGE thank you to all our fantastic speakers and presentations. Please feel free to reuse this content in your own presentations and events.
|
||||
If you do this, we do ask as a common courtesey to attribute the content to the origial author as appropriate.
|
||||
|
||||
All sessions are also on-demand on the [Visual Studio YouTube channel](https://www.youtube.com/playlist?list=PLReL099Y5nRd04p81Q7p5TtyjCrj9tz1t).
|
||||
Also check out more .NET presentations and workshops here: [https://github.com/dotnet-presentations/home](https://github.com/dotnet-presentations/home)
|
||||
|
||||
See you next year!
|
Двоичные данные
2019/Technical/Tour-of-Microsoft-Reference-ASPNET-Core-App-eShopOnWeb-Steve-Smith-Ardalis.pdf
Normal file
Двоичные данные
2019/Technical/Why you should create your next library using .NET Standard.pptx
Normal file
|
@ -0,0 +1,25 @@
|
|||
**/.classpath
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
|
@ -0,0 +1,330 @@
|
|||
## 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
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUNIT
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_i.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# JustCode is a .NET coding add-in
|
||||
.JustCode
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
!BlazorWeather.Electron/packages/*
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
# CodeRush
|
||||
.cr/
|
||||
|
||||
# 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/
|
|
@ -0,0 +1,10 @@
|
|||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p>Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
|
@ -0,0 +1,21 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<RazorLangVersion>3.0</RazorLangVersion>
|
||||
<RootNamespace>BlazorWeather</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\WeatherClientLib\WeatherClientLib.csproj" />
|
||||
<ProjectReference Include="..\WeatherServiceML.Abstractions\WeatherServiceML.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,44 @@
|
|||
@inject IWeatherClassifier WeatherClassifier
|
||||
|
||||
<h3>Weather Cam</h3>
|
||||
|
||||
<div class="image-predictor">
|
||||
<div class="image-selector">
|
||||
@foreach (var place in cams.Keys)
|
||||
{
|
||||
<button class="@(cams[place] == camUrl ? "btn-link selected" : "btn-link")"
|
||||
@onclick="() => Update(cams[place])">
|
||||
@place
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="result-pane">
|
||||
<img src="@camUrl" height="300" />
|
||||
<span class="result-label">@(weatherDescription == null ? "Hmm, the weather looks..." : weatherDescription)</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@code {
|
||||
IDictionary<string, string> cams = new Dictionary<string, string>()
|
||||
{
|
||||
{ "Century Link Field", "weatherImages/century-link.png" },
|
||||
{ "Paramount Theater", "weatherImages/paramount-theater.jpg" },
|
||||
{ "Golden Gardens Park", "weatherImages/golden-gardens.jpg" }
|
||||
};
|
||||
string camUrl;
|
||||
string weatherDescription;
|
||||
|
||||
protected override Task OnParametersSetAsync()
|
||||
{
|
||||
return Update(cams.Values.First());
|
||||
}
|
||||
|
||||
async Task Update(string imgUrl)
|
||||
{
|
||||
weatherDescription = null;
|
||||
camUrl = imgUrl;
|
||||
weatherDescription = await WeatherClassifier.ClassifyWeather(camUrl);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
@page "/"
|
||||
@implements IDisposable
|
||||
@inject IWeatherForecastService WeatherForecastService
|
||||
|
||||
@if (currentWeather == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div id="main" class="@GetBackgroundClass()">
|
||||
<div class="weather-now">
|
||||
<h1>SEATTLE</h1>
|
||||
<div class="location-img"></div>
|
||||
<div class="temperature">
|
||||
@GetTemperature()
|
||||
<TemperatureUnitPicker @bind-TemperatureUnit="temperatureUnit" />
|
||||
</div>
|
||||
<div class="summary">
|
||||
<img class="weather-img" src="@currentWeather.WeartherUri" alt="@currentWeather.WeatherText" />
|
||||
@currentWeather.WeatherText
|
||||
</div>
|
||||
<div class="update-info">Updated @GetTimeToDisplay()</div>
|
||||
<div class="metrics">
|
||||
<div>UV index <p>@currentWeather.UVIndex</p></div>
|
||||
<div>Barometer <p>@currentWeather.Pressure</p></div>
|
||||
<div>Humidity <p>@currentWeather.RelativeHumidity%</p></div>
|
||||
<div>Wind <p>@currentWeather.WindSpeed <span class="wind-details">mph @currentWeather.WindDirection</span></p></div>
|
||||
</div>
|
||||
<MLWeatherCam />
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@code {
|
||||
WeatherResponse currentWeather;
|
||||
string temperatureUnit = "F";
|
||||
|
||||
CancellationTokenSource streamingWeatherCTS = new CancellationTokenSource();
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
currentWeather = await WeatherForecastService.GetWeather();
|
||||
}
|
||||
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
_ = GetWeatherUpdates();
|
||||
}
|
||||
}
|
||||
|
||||
async Task GetWeatherUpdates()
|
||||
{
|
||||
await foreach (var weatherResponse in WeatherForecastService.GetStreamingWeather(streamingWeatherCTS.Token))
|
||||
{
|
||||
currentWeather = weatherResponse;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
string GetBackgroundClass()
|
||||
{
|
||||
if (currentWeather == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
else if (!currentWeather.IsDayTime)
|
||||
{
|
||||
return "night";
|
||||
}
|
||||
else if (currentWeather.Temperature > 60)
|
||||
{
|
||||
return "warm";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "cold";
|
||||
}
|
||||
}
|
||||
|
||||
void SwitchTemperatureUnit()
|
||||
{
|
||||
temperatureUnit = temperatureUnit == "F" ? "C" : "F";
|
||||
}
|
||||
|
||||
float GetTemperature()
|
||||
=> temperatureUnit == "F" ? currentWeather.Temperature : TemperatureAsCelsius(currentWeather.Temperature);
|
||||
|
||||
float TemperatureAsCelsius(float f)
|
||||
=> (float)Math.Round((f - 23f) / 1.8f);
|
||||
|
||||
string GetTimeToDisplay()
|
||||
=> currentWeather.RetrievedTime.ToDateTimeOffset().ToLocalTime().ToString("T");
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
streamingWeatherCTS.Cancel();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
@inherits LayoutComponentBase
|
||||
|
||||
@Body
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<div class="unit-switch" @onclick="SwitchTemperatureUnit">
|
||||
<span class="temp-unit">@TemperatureUnit</span>
|
||||
<span class="temp-unit-option">/ @(TemperatureUnit == "F" ? "C" : "F")</span>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string TemperatureUnit { get; set; } = "F";
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string> TemperatureUnitChanged { get; set; }
|
||||
|
||||
Task SwitchTemperatureUnit()
|
||||
{
|
||||
TemperatureUnit = TemperatureUnit == "F" ? "C" : "F";
|
||||
return TemperatureUnitChanged.InvokeAsync(TemperatureUnit);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
@using System.Net.Http
|
||||
@using System.Threading
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.JSInterop
|
||||
@using BlazorWeather
|
||||
@using BlazorWeather.Shared
|
||||
@using Weather
|
||||
@using Google.Protobuf.WellKnownTypes
|
||||
@using Grpc.Core
|
||||
@using WeatherClientLib
|
||||
@using WeatherServiceML
|
После Ширина: | Высота: | Размер: 28 KiB |
|
@ -0,0 +1,219 @@
|
|||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
color: white;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#main {
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.weather-now, .weather-graph {
|
||||
flex-grow: 1;
|
||||
margin: 1.5rem;
|
||||
width: calc(50% - 3rem);
|
||||
}
|
||||
|
||||
.weather-now {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.weather-now h1 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 200;
|
||||
letter-spacing: 1px;
|
||||
text-align: center;
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
|
||||
.location-img {
|
||||
flex-grow: 1;
|
||||
background: url('spaceneedle.png');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.location-img img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.temperature {
|
||||
font-size: 6rem;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.temperature::after {
|
||||
content: "°";
|
||||
position: absolute;
|
||||
font-size: 5rem;
|
||||
top: 0.3rem;
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.unit-switch {
|
||||
position: absolute;
|
||||
bottom: 0.75rem;
|
||||
left: calc(100% + 2rem);
|
||||
width: 200px;
|
||||
font-size: 3rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.temp-unit-option {
|
||||
font-size: 1.5rem;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.summary {
|
||||
text-transform: uppercase;
|
||||
font-size: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.weather-img {
|
||||
margin-right: -10px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.metrics {
|
||||
display: flex;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.metrics > div {
|
||||
background: linear-gradient(-45deg, rgba(255,255,255,0.05), rgba(255,255,255,0.35));
|
||||
padding: 0.75rem;
|
||||
text-align: center;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
border-radius: 1rem;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.metrics > div:not(:last-of-type) {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.metrics > div p {
|
||||
margin: 0;
|
||||
font-weight: 200;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.update-info {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.warm {
|
||||
background-image: linear-gradient(#F6CC66, #FCA184);
|
||||
}
|
||||
|
||||
.cold {
|
||||
background-image: linear-gradient(#BDE3FA, #A5C9FD);
|
||||
}
|
||||
|
||||
.night {
|
||||
background-image: linear-gradient(#172941, #3C6683);
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
#main {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.weather-now, .weather-graph {
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.location-img {
|
||||
min-height: 30vh;
|
||||
}
|
||||
|
||||
.weather-graph {
|
||||
height: 50vh;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.wind-details {
|
||||
display: none; /* not enough space on mobile */
|
||||
}
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
background: transparent;
|
||||
border: 1px solid #fff;
|
||||
padding: 12px;
|
||||
font-size: 15px;
|
||||
/*optional*/
|
||||
/*input has OS specific font-family*/
|
||||
border-radius: 1rem;
|
||||
border-bottom-right-radius: 0;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.btn-link.selected {
|
||||
background: linear-gradient(-45deg, rgba(255,255,255,0.05), rgba(255,255,255,0.35));
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.image-predictor {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.result-label {
|
||||
float: left;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background: rgba(0,0,0,0.5);
|
||||
text-align: center;
|
||||
font-size: 1.25rem;
|
||||
padding: 12px;
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
}
|
||||
|
||||
.result-pane {
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.result-pane img {
|
||||
border-radius: 1rem;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.image-selector {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 10px;
|
||||
width: 200px;
|
||||
margin-left: -200px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 40px;
|
||||
font-size: 2rem;
|
||||
margin-bottom: 0;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<OutputPath>bin\$(Configuration)</OutputPath>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<DefaultItemExcludes>${DefaultItemExcludes};node_modules\**;package-lock.json</DefaultItemExcludes>
|
||||
<RazorLangVersion>3.0</RazorLangVersion>
|
||||
<RestoreAdditionalProjectSources>
|
||||
$(RestoreAdditionalProjectSources);
|
||||
.\packages;
|
||||
</RestoreAdditionalProjectSources>
|
||||
<RootNamespace>BlazorWeather</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Electron" Version="0.1.0-preview1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" Version="3.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="EnsureNpmRestored" BeforeTargets="CoreBuild" Condition="!Exists('node_modules')">
|
||||
<Message Importance="high" Text="Restoring dependencies using 'npm'. This may take several minutes..." />
|
||||
<Exec Command="npm install" />
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="packages\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BlazorWeather.Core\BlazorWeather.Core.csproj" />
|
||||
<ProjectReference Include="..\WeatherServiceML.Abstractions\WeatherServiceML.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,12 @@
|
|||
using Microsoft.AspNetCore.Components.Electron;
|
||||
|
||||
namespace BlazorWeather
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
ComponentsElectron.Run<Startup>("wwwroot/index.html");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
using Microsoft.AspNetCore.Components.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using static Weather.Weather;
|
||||
using WeatherClientLib;
|
||||
using System;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using WeatherServiceML;
|
||||
|
||||
namespace BlazorWeather
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
var configuration = new ConfigurationBuilder()
|
||||
.AddJsonFile("appsettings.json", true, true)
|
||||
.Build();
|
||||
|
||||
services.AddGrpcWeatherForecastService(options =>
|
||||
{
|
||||
options.Address = new Uri(configuration["WeatherServiceUri"]);
|
||||
});
|
||||
services.AddScoped<IWeatherClassifier, WasmWeatherClassifier>();
|
||||
}
|
||||
|
||||
public void Configure(IComponentsApplicationBuilder app)
|
||||
{
|
||||
app.AddComponent<App>("app");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"WeatherServiceUri": "https://localhost:5001"
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "components-electron-sample",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "electron ."
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"electron": "^3.0.4",
|
||||
"socket.io": "^2.0.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html, body {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
color: white;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#main {
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.weather-now, .weather-graph {
|
||||
flex-grow: 1;
|
||||
margin: 1.5rem;
|
||||
width: calc(50% - 3rem);
|
||||
}
|
||||
|
||||
.weather-now {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.weather-now h1 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 200;
|
||||
letter-spacing: 1px;
|
||||
text-align: center;
|
||||
margin: 0 0 1rem 0;
|
||||
}
|
||||
|
||||
.location-img {
|
||||
flex-grow: 1;
|
||||
background: url('spaceneedle.png');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.location-img img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.temperature {
|
||||
font-size: 6rem;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.temperature::after {
|
||||
content: "°";
|
||||
position: absolute;
|
||||
font-size: 5rem;
|
||||
top: 0.3rem;
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.unit-switch {
|
||||
position: absolute;
|
||||
bottom: 0.75rem;
|
||||
left: calc(100% + 2rem);
|
||||
width: 200px;
|
||||
font-size: 3rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.temp-unit-option {
|
||||
font-size: 1.5rem;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.summary {
|
||||
text-transform: uppercase;
|
||||
font-size: 2rem;
|
||||
margin-bottom: 0.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.weather-img {
|
||||
margin-right: -10px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.metrics {
|
||||
display: flex;
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
.metrics > div {
|
||||
background: linear-gradient(-45deg, rgba(255,255,255,0.05), rgba(255,255,255,0.35));
|
||||
padding: 0.75rem;
|
||||
text-align: center;
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
border-radius: 1rem;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.metrics > div:not(:last-of-type) {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
|
||||
.metrics > div p {
|
||||
margin: 0;
|
||||
font-weight: 200;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.update-info {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.warm {
|
||||
background-image: linear-gradient(#F6CC66, #FCA184);
|
||||
}
|
||||
|
||||
.cold {
|
||||
background-image: linear-gradient(#BDE3FA, #A5C9FD);
|
||||
}
|
||||
|
||||
.night {
|
||||
background-image: linear-gradient(#172941, #3C6683);
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
#main {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.weather-now, .weather-graph {
|
||||
width: unset;
|
||||
}
|
||||
|
||||
.location-img {
|
||||
min-height: 30vh;
|
||||
}
|
||||
|
||||
.weather-graph {
|
||||
height: 50vh;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.wind-details {
|
||||
display: none; /* not enough space on mobile */
|
||||
}
|
||||
}
|
||||
|
||||
.btn-link {
|
||||
background: transparent;
|
||||
border: 1px solid #fff;
|
||||
padding: 12px;
|
||||
font-size: 15px;
|
||||
/*optional*/
|
||||
/*input has OS specific font-family*/
|
||||
border-radius: 1rem;
|
||||
border-bottom-right-radius: 0;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.btn-link.selected {
|
||||
background: linear-gradient(-45deg, rgba(255,255,255,0.05), rgba(255,255,255,0.35));
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.image-predictor {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.result-label {
|
||||
float: left;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background: rgba(0,0,0,0.5);
|
||||
text-align: center;
|
||||
font-size: 1.25rem;
|
||||
padding: 12px;
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
}
|
||||
|
||||
.result-pane {
|
||||
float: left;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.result-pane img {
|
||||
border-radius: 1rem;
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
|
||||
.image-selector {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-right: 10px;
|
||||
width: 200px;
|
||||
margin-left: -200px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 40px;
|
||||
font-size: 2rem;
|
||||
margin-bottom: 0;
|
||||
}
|
Двоичные данные
2019/Technical/keynote/BlazorWeather.Electron/wwwroot/css/spaceneedle.png
Normal file
После Ширина: | Высота: | Размер: 28 KiB |
После Ширина: | Высота: | Размер: 31 KiB |
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Weather.BlazorElectron</title>
|
||||
<base href="./" />
|
||||
<link href="css/site.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<app>Loading...</app>
|
||||
|
||||
<script src="../bin/Debug/netcoreapp3.0/electron-js/components.electron.js"></script>
|
||||
</body>
|
||||
</html>
|
Двоичные данные
2019/Technical/keynote/BlazorWeather.Electron/wwwroot/weatherImages/century-link.png
Normal file
После Ширина: | Высота: | Размер: 592 KiB |
Двоичные данные
2019/Technical/keynote/BlazorWeather.Electron/wwwroot/weatherImages/golden-gardens.jpg
Normal file
После Ширина: | Высота: | Размер: 80 KiB |
Двоичные данные
2019/Technical/keynote/BlazorWeather.Electron/wwwroot/weatherImages/paramount-theater.jpg
Normal file
После Ширина: | Высота: | Размер: 127 KiB |
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
<RootNamespace>BlazorWeather</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BlazorWeather.Core\BlazorWeather.Core.csproj" />
|
||||
<ProjectReference Include="..\WeatherServiceML\WeatherServiceML.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,16 @@
|
|||
@page "/error"
|
||||
|
||||
|
||||
<h1 class="text-danger">Error.</h1>
|
||||
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||
|
||||
<h3>Development Mode</h3>
|
||||
<p>
|
||||
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
|
||||
</p>
|
||||
<p>
|
||||
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
|
||||
It can result in displaying sensitive information from exceptions to end users.
|
||||
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
|
||||
and restarting the app.
|
||||
</p>
|
|
@ -0,0 +1,19 @@
|
|||
@page "/"
|
||||
@namespace BlazorWeather.Pages
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Weather.Blazor</title>
|
||||
<base href="~/" />
|
||||
<link href="_content/BlazorWeather.Core/weather.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
@(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
|
||||
|
||||
<script src="_framework/blazor.server.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,28 @@
|
|||
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.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace BlazorWeather
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder =>
|
||||
{
|
||||
webBuilder.UseStartup<Startup>();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:56911/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"BlazorWeather.Server": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:56919/"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.HttpsPolicy;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using static Weather.Weather;
|
||||
using WeatherClientLib;
|
||||
using WeatherServiceML;
|
||||
|
||||
namespace BlazorWeather
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddRazorPages();
|
||||
services.AddServerSideBlazor();
|
||||
services.AddGrpcWeatherForecastService(options =>
|
||||
{
|
||||
options.Address = new Uri(Configuration["WeatherServiceUri"]);
|
||||
});
|
||||
services.AddScoped<IWeatherClassifier, MLWeatherClassifier>();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/Error");
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapBlazorHub();
|
||||
endpoints.MapFallbackToPage("/_Host");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
@using System.Net.Http
|
||||
@using System.Threading
|
||||
@using Microsoft.AspNetCore.Authorization
|
||||
@using Microsoft.AspNetCore.Components.Authorization
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.JSInterop
|
||||
@using BlazorWeather
|
||||
@using BlazorWeather.Shared
|
||||
@using Weather
|
||||
@using Google.Protobuf.WellKnownTypes
|
||||
@using Grpc.Core
|
||||
@using WeatherClientLib
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Debug",
|
||||
"System": "Information",
|
||||
"Microsoft": "Information"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"WeatherServiceUri": "https://localhost:5001"
|
||||
}
|
После Ширина: | Высота: | Размер: 31 KiB |
Двоичные данные
2019/Technical/keynote/BlazorWeather.Server/wwwroot/weatherImages/century-link.png
Normal file
После Ширина: | Высота: | Размер: 592 KiB |
Двоичные данные
2019/Technical/keynote/BlazorWeather.Server/wwwroot/weatherImages/golden-gardens.jpg
Normal file
После Ширина: | Высота: | Размер: 80 KiB |
Двоичные данные
2019/Technical/keynote/BlazorWeather.Server/wwwroot/weatherImages/paramount-theater.jpg
Normal file
После Ширина: | Высота: | Размер: 127 KiB |
|
@ -0,0 +1,22 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.1</TargetFramework>
|
||||
<RazorLangVersion>3.0</RazorLangVersion>
|
||||
<RootNamespace>BlazorWeather</RootNamespace>
|
||||
<BlazorLinkOnBuild>false</BlazorLinkOnBuild>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Blazor" Version="3.0.0-preview9.19465.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="3.0.0-preview9.19465.2" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Blazor.HttpClient" Version="3.0.0-preview9.19465.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Blazor.DevServer" Version="3.0.0-preview9.19465.2" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\BlazorWeather.Core\BlazorWeather.Core.csproj" />
|
||||
<ProjectReference Include="..\WeatherServiceML.Abstractions\WeatherServiceML.Abstractions.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,16 @@
|
|||
using Microsoft.AspNetCore.Blazor.Hosting;
|
||||
|
||||
namespace BlazorWeather
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IWebAssemblyHostBuilder CreateHostBuilder(string[] args) =>
|
||||
BlazorWebAssemblyHost.CreateDefaultBuilder()
|
||||
.UseBlazorStartup<Startup>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:56909/",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"BlazorWeather.WebAssembly": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "http://localhost:56912/"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using Microsoft.AspNetCore.Components.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using WeatherServiceML;
|
||||
using WeatherClientLib;
|
||||
|
||||
namespace BlazorWeather
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddHttpWeatherForecastService(options =>
|
||||
{
|
||||
options.Address = new System.Uri("https://localhost:5001/json");
|
||||
});
|
||||
services.AddScoped<IWeatherClassifier, WasmWeatherClassifier>();
|
||||
}
|
||||
|
||||
public void Configure(IComponentsApplicationBuilder app)
|
||||
{
|
||||
app.AddComponent<App>("app");
|
||||
}
|
||||
}
|
||||
}
|
После Ширина: | Высота: | Размер: 31 KiB |
После Ширина: | Высота: | Размер: 201 KiB |
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>BlazorWeather.WebAssembly</title>
|
||||
<base href="/" />
|
||||
<link href="_content/BlazorWeather.Core/weather.css" rel="stylesheet" />
|
||||
<link rel="manifest" href="manifest.json">
|
||||
</head>
|
||||
<body>
|
||||
<app>Loading...</app>
|
||||
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('service-worker.js');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"short_name": "Weather",
|
||||
"name": "Blazor Weather",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/icon-512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": "/",
|
||||
"background_color": "#aaaaaa",
|
||||
"display": "standalone",
|
||||
"scope": "/ ",
|
||||
"theme_color": "#333333"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
self.addEventListener('install', async event => {
|
||||
console.log('Installing service worker...');
|
||||
self.skipWaiting();
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', event => {
|
||||
return null;
|
||||
});
|
Двоичные данные
2019/Technical/keynote/BlazorWeather.WebAssembly/wwwroot/weatherImages/century-link.png
Normal file
После Ширина: | Высота: | Размер: 592 KiB |
Двоичные данные
2019/Technical/keynote/BlazorWeather.WebAssembly/wwwroot/weatherImages/golden-gardens.jpg
Normal file
После Ширина: | Высота: | Размер: 80 KiB |
Двоичные данные
2019/Technical/keynote/BlazorWeather.WebAssembly/wwwroot/weatherImages/paramount-theater.jpg
Normal file
После Ширина: | Высота: | Размер: 127 KiB |
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,19 @@
|
|||
Any raw assets you want to be deployed with your application can be placed in
|
||||
this directory (and child directories) and given a Build Action of "AndroidAsset".
|
||||
|
||||
These files will be deployed with you package and will be accessible using Android's
|
||||
AssetManager, like this:
|
||||
|
||||
public class ReadAsset : Activity
|
||||
{
|
||||
protected override void OnCreate (Bundle bundle)
|
||||
{
|
||||
base.OnCreate (bundle);
|
||||
|
||||
InputStream input = Assets.Open ("my_asset.txt");
|
||||
}
|
||||
}
|
||||
|
||||
Additionally, some Android functions will automatically load asset files:
|
||||
|
||||
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
|
||||
using Android.App;
|
||||
using Android.Content.PM;
|
||||
using Android.Runtime;
|
||||
using Android.Views;
|
||||
using Android.Widget;
|
||||
using Android.OS;
|
||||
using Weather.MobileCore;
|
||||
|
||||
namespace Weather.Droid
|
||||
{
|
||||
[Activity(Label = "Weather", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
|
||||
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
|
||||
{
|
||||
protected override void OnCreate(Bundle savedInstanceState)
|
||||
{
|
||||
TabLayoutResource = Resource.Layout.Tabbar;
|
||||
ToolbarResource = Resource.Layout.Toolbar;
|
||||
|
||||
base.OnCreate(savedInstanceState);
|
||||
global::Xamarin.Forms.Forms.SetFlags("CollectionView_Experimental");
|
||||
global::Xamarin.Forms.FormsMaterial.Init(this, savedInstanceState);
|
||||
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
|
||||
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
|
||||
LoadApplication(new App());
|
||||
}
|
||||
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
|
||||
{
|
||||
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.Weather.Droid">
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
|
||||
<application android:label="Weather.Droid.Android" android:networkSecurityConfig="@xml/network_security_config"></application>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
</manifest>
|
|
@ -0,0 +1,34 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Android.App;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Weather.Droid.Android")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Weather.Droid.Android")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
// Add some common permissions, these can be removed if not needed
|
||||
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
|
||||
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
|
|
@ -0,0 +1,50 @@
|
|||
Images, layout descriptions, binary blobs and string dictionaries can be included
|
||||
in your application as resource files. Various Android APIs are designed to
|
||||
operate on the resource IDs instead of dealing with images, strings or binary blobs
|
||||
directly.
|
||||
|
||||
For example, a sample Android app that contains a user interface layout (main.xml),
|
||||
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
|
||||
would keep its resources in the "Resources" directory of the application:
|
||||
|
||||
Resources/
|
||||
drawable-hdpi/
|
||||
icon.png
|
||||
|
||||
drawable-ldpi/
|
||||
icon.png
|
||||
|
||||
drawable-mdpi/
|
||||
icon.png
|
||||
|
||||
layout/
|
||||
main.xml
|
||||
|
||||
values/
|
||||
strings.xml
|
||||
|
||||
In order to get the build system to recognize Android resources, set the build action to
|
||||
"AndroidResource". The native Android APIs do not operate directly with filenames, but
|
||||
instead operate on resource IDs. When you compile an Android application that uses resources,
|
||||
the build system will package the resources for distribution and generate a class called
|
||||
"Resource" that contains the tokens for each one of the resources included. For example,
|
||||
for the above Resources layout, this is what the Resource class would expose:
|
||||
|
||||
public class Resource {
|
||||
public class drawable {
|
||||
public const int icon = 0x123;
|
||||
}
|
||||
|
||||
public class layout {
|
||||
public const int main = 0x456;
|
||||
}
|
||||
|
||||
public class strings {
|
||||
public const int first_string = 0xabc;
|
||||
public const int second_string = 0xbcd;
|
||||
}
|
||||
}
|
||||
|
||||
You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
|
||||
to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
|
||||
string in the dictionary file values/strings.xml.
|
15057
2019/Technical/keynote/Mobile/Weather.Android/Resources/Resource.designer.cs
сгенерированный
Normal file
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/drawable-nodpi/spaceneedle.png
Normal file
После Ширина: | Высота: | Размер: 44 KiB |
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.TabLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/sliding_tabs"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
app:tabIndicatorColor="@android:color/white"
|
||||
app:tabGravity="fill"
|
||||
app:tabMode="fixed" />
|
|
@ -0,0 +1,9 @@
|
|||
<android.support.v7.widget.Toolbar
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
|
||||
android:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/launcher_background" />
|
||||
<foreground android:drawable="@mipmap/launcher_foreground" />
|
||||
</adaptive-icon>
|
|
@ -0,0 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/launcher_background" />
|
||||
<foreground android:drawable="@mipmap/launcher_foreground" />
|
||||
</adaptive-icon>
|
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/mipmap-hdpi/icon.png
Normal file
После Ширина: | Высота: | Размер: 4.6 KiB |
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/mipmap-hdpi/launcher_foreground.png
Normal file
После Ширина: | Высота: | Размер: 11 KiB |
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/mipmap-mdpi/icon.png
Normal file
После Ширина: | Высота: | Размер: 2.7 KiB |
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/mipmap-mdpi/launcher_foreground.png
Normal file
После Ширина: | Высота: | Размер: 6.3 KiB |
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/mipmap-xhdpi/icon.png
Normal file
После Ширина: | Высота: | Размер: 6.9 KiB |
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/mipmap-xhdpi/launcher_foreground.png
Normal file
После Ширина: | Высота: | Размер: 18 KiB |
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/mipmap-xxhdpi/icon.png
Normal file
После Ширина: | Высота: | Размер: 12 KiB |
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/mipmap-xxhdpi/launcher_foreground.png
Normal file
После Ширина: | Высота: | Размер: 33 KiB |
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/mipmap-xxxhdpi/icon.png
Normal file
После Ширина: | Высота: | Размер: 19 KiB |
Двоичные данные
2019/Technical/keynote/Mobile/Weather.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png
Normal file
После Ширина: | Высота: | Размер: 51 KiB |
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="launcher_background">#FFFFFF</color>
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
</resources>
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<resources>
|
||||
|
||||
<style name="MainTheme" parent="MainTheme.Base">
|
||||
</style>
|
||||
<!-- Base theme applied no matter what API -->
|
||||
<style name="MainTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!--If you are using revision 22.1 please use just windowNoTitle. Without android:-->
|
||||
<item name="windowNoTitle">true</item>
|
||||
<!--We will be using the toolbar so no need to show ActionBar-->
|
||||
<item name="windowActionBar">false</item>
|
||||
<!-- Set theme colors from http://www.google.com/design/spec/style/color.html#color-color-palette -->
|
||||
<!-- colorPrimary is used for the default action bar background -->
|
||||
<item name="colorPrimary">#2196F3</item>
|
||||
<!-- colorPrimaryDark is used for the status bar -->
|
||||
<item name="colorPrimaryDark">#1976D2</item>
|
||||
<!-- colorAccent is used as the default value for colorControlActivated
|
||||
which is used to tint widgets -->
|
||||
<item name="colorAccent">#FF4081</item>
|
||||
<!-- You can also set colorControlNormal, colorControlActivated
|
||||
colorControlHighlight and colorSwitchThumbNormal. -->
|
||||
<item name="windowActionModeOverlay">true</item>
|
||||
|
||||
<item name="android:datePickerDialogTheme">@style/AppCompatDialogStyle</item>
|
||||
</style>
|
||||
|
||||
<style name="AppCompatDialogStyle" parent="Theme.AppCompat.Light.Dialog">
|
||||
<item name="colorAccent">#FF4081</item>
|
||||
</style>
|
||||
</resources>
|