Skip to content

Commit

Permalink
Add project files.
Browse files Browse the repository at this point in the history
  • Loading branch information
SQL-MisterMagoo committed Aug 8, 2019
1 parent 7815f15 commit edc3bf8
Show file tree
Hide file tree
Showing 16 changed files with 651 additions and 0 deletions.
Binary file added Blazor.PWA.MSBuild-NuGet-Icon.pdn
Binary file not shown.
Binary file added Blazor.PWA.MSBuild-NuGet-Icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
75 changes: 75 additions & 0 deletions Blazor.PWA.MSBuild.Tasks/Blazor.PWA.MSBuild.Tasks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard1.6</TargetFramework>
<!-- Suppresses the warnings about the package not having assemblies in lib/*/.dll.-->
<NoPackageAnalysis>true</NoPackageAnalysis>
<!-- Change the default location where NuGet will put the build output -->
<BuildOutputTargetFolder>tasks</BuildOutputTargetFolder>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>Mister Magoo</Authors>
<Copyright>2019 SQL-MisterMagoo</Copyright>
<DevelopmentDependency>true</DevelopmentDependency>
<Description>The easiest way to turn your Client Side Blazor application into a PWA with offline capabilities.
Add this package to your build process and it will generate the files you need to become PWA compatible.
This does not make your application ready for distribution through "App Stores" - it just provides basic PWA functionality.</Description>
<PackageId>Blazor.PWA.MSBuild</PackageId>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<PackageLicenseExpression></PackageLicenseExpression>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<PackageProjectUrl>https://github.com/SQL-MisterMagoo/Blazor.PWA.MSBuild/src/Blazor.PWA.MSBuild</PackageProjectUrl>
<PackageTags>Blazor,Build,MSBuild,PWA,Manifest,ServiceWorker,C#,DotNET,Web,Client</PackageTags>
<Product>Blazor.PWA.MSBuild</Product>
<RepositoryUrl>https://github.com/SQL-MisterMagoo/Blazor.PWA.MSBuild</RepositoryUrl>
<PackageIconUrl>https://github.com/SQL-MisterMagoo/Blazor.PWA.MSBuild/src/Blazor.PWA.MSBuild/Blazor.PWA.MSBuild-NuGet-Icon.png</PackageIconUrl>
<RepositoryType>git</RepositoryType>
<PackageReleaseNotes>This is a beta release of a very basic PWA build target.
Just by including this in the build, it can generate the basic requirements for an installable PWA for client side Blazor.
The result is not an App Store package, it is simply the basic requirements for PWA.
I will add more network caching strategies, but for now it has just one - cache all local assets.</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
<PackageReference Update="@(PackageReference)" PrivateAssets="All" />
</ItemGroup>

<ItemGroup>
<None Include="..\LICENSE.txt;..\README.md;">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>

<ItemGroup>
<Content Include="build\Blazor.PWA.MSBuild.Manifest.targets">
<PackagePath>build\</PackagePath>
<Pack>True</Pack>
</Content>
<Content Include="build\Blazor.PWA.MSBuild.ServiceWorker.targets">
<PackagePath>build\</PackagePath>
<Pack>True</Pack>
</Content>
<Content Include="build\Blazor.PWA.MSBuild.ServiceWorkerRegister.targets">
<PackagePath>build\</PackagePath>
<Pack>True</Pack>
</Content>
<Content Include="build\Blazor.PWA.MSBuild.targets">
<PackagePath>build\</PackagePath>
<Pack>True</Pack>
</Content>
<Content Include="Templates\**\*.js">
<Pack>True</Pack>
<PackagePath>Templates\</PackagePath>
</Content>
<Content Include="Templates\Images\**\*.*">
<Pack>True</Pack>
<PackagePath>Templates\</PackagePath>
</Content>

</ItemGroup>

<ItemGroup>
<Folder Include="Templates\Images\" />
</ItemGroup>

</Project>
7 changes: 7 additions & 0 deletions Blazor.PWA.MSBuild.Tasks/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project>
<PropertyGroup>
<VersionPrefix>0.0.1</VersionPrefix>
<VersionSuffix>beta$([System.DateTime]::Now.ToString("yyyyMMdd-HHmmss"))</VersionSuffix>
<VersionSuffix Condition="'$(Configuration)' == 'Release'">beta$([System.DateTime]::Now.ToString("yyyyMMdd-HH"))</VersionSuffix>
</PropertyGroup>
</Project>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
self.addEventListener(networkFetchEvent, event => {
const requestUrl = new URL(event.request.url);
if (requestUrl.origin === location.origin) {
if (requestUrl.pathname === baseURL) {
event.respondWith(caches.match(indexURL));
return;
}
}
event.respondWith(
caches.match(event.request)
.then(response => {
if (response) {
return response;
}
return fetch(event.request)
.then(response => {
if (response.ok) {
if (requestUrl.origin === location.origin) {
caches.open(staticCacheName).then(cache => {
cache.put(event.request.url, response);
});
}
}
return response.clone();
});
}).catch(error => {
console.error(error);
})
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// * listen for the install event and pre-cache anything in filesToCache * //
self.addEventListener(swInstallEvent, event => {
self.skipWaiting();
event.waitUntil(
caches.open(staticCacheName)
.then(cache => {
return cache.addAll(requiredFiles);
})
);
});
self.addEventListener(swActivateEvent, function (event) {
event.waitUntil(
caches.keys().then(function (cacheNames) {
return Promise.all(
cacheNames.map(function (cacheName) {
if (staticCacheName !== cacheName && cacheName.startsWith(staticCachePrefix)) {
return caches.delete(cacheName);
}
})
);
})
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
window.updateAvailable = new Promise(function (resolve, reject) {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register(serviceWorkerFileName)
.then(function (registration) {
console.log('Registration successful, scope is:', registration.scope);
registration.onupdatefound = () => {
const installingWorker = registration.installing;
installingWorker.onstatechange = () => {
switch (installingWorker.state) {
case swInstalledEvent:
if (navigator.serviceWorker.controller) {
resolve(true);
} else {
resolve(false);
}
break;
default:
}
};
};
})
.catch(error =>
console.log('Service worker registration failed, error:', error));
}
});
window['updateAvailable']
.then(isAvailable => {
if (isAvailable) {
alert("Update available. Reload the page when convenient.");
}
});

window.addEventListener('beforeinstallprompt', function (e) {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
window.PWADeferredPrompt = e;

showAddToHomeScreen();

});

function showAddToHomeScreen() {
var pwaInstallPrompt = document.createElement('div');
var pwaInstallButton = document.createElement('button');
var pwaCancelButton = document.createElement('button');

pwaInstallPrompt.id = 'pwa-install-prompt';
pwaInstallPrompt.style.position = 'absolute';
pwaInstallPrompt.style.bottom = '0';
pwaInstallPrompt.style.display = 'flex';
pwaInstallPrompt.style.width = '100vw';
pwaInstallPrompt.style.backgroundColor='darkslategrey';
pwaInstallPrompt.style.color='white';
pwaInstallPrompt.style.fontSize='2rem';

pwaInstallButton.style.marginLeft='auto';
pwaInstallButton.style.width='4em';
pwaInstallButton.style.backgroundColor='green';
pwaInstallButton.style.color='white';

pwaCancelButton.style.marginLeft='0.3rem';
pwaCancelButton.style.backgroundColor='darkslategray';
pwaCancelButton.style.color='white';

pwaInstallPrompt.innerText = 'Add to your homescreen!';
pwaInstallButton.innerText = 'OK';
pwaCancelButton.innerText = 'Ignore';

pwaInstallPrompt.appendChild(pwaInstallButton);
pwaInstallPrompt.appendChild(pwaCancelButton);
document.body.appendChild(pwaInstallPrompt);

pwaInstallButton.addEventListener('click', addToHomeScreen);
pwaCancelButton.addEventListener('click', hideAddToHomeScreen);
setTimeout(hideAddToHomeScreen, 10000);
}

function hideAddToHomeScreen() {
var pwa = document.getElementById('pwa-install-prompt');
if (pwa) document.body.removeChild(pwa);
}

function addToHomeScreen(s, e) {
hideAddToHomeScreen();
if (window.PWADeferredPrompt) {
window.PWADeferredPrompt.prompt();
window.PWADeferredPrompt.userChoice
.then(function (choiceResult) {
window.PWADeferredPrompt = null;
});
}
}
86 changes: 86 additions & 0 deletions Blazor.PWA.MSBuild.Tasks/build/Blazor.PWA.MSBuild.Manifest.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<Project>
<Target Name="BuildServiceWorkerManifest" Condition="!Exists('$(WWWRoot)$(ManifestFileName)') Or '$(ManifestForce)'=='true'">
<!-- bit of info in the build output -->
<Message Importance="high" Text="Building Manifest $(ManifestFileName)" Condition="!Exists('$(WWWRoot)$(ManifestFileName)')"/>
<Message Importance="high" Text="Re-Building Manifest $(ManifestFileName)" Condition="Exists('$(WWWRoot)$(ManifestFileName)')"/>

<PropertyGroup Label="Manifest">

<!-- A manifest needs names - if none were provided, use the Solution/Project names -->
<ManifestShortName Condition="'$(ManifestShortName)' == ''">$(SolutionName)</ManifestShortName>
<ManifestLongName Condition="'$(ManifestLongName)' == ''">$(ProjectName)</ManifestLongName>

<!-- Base URL for the app -->
<ManifestBaseUrl Condition="'$(ManifestBaseUrl)' == ''">/</ManifestBaseUrl>

<!-- Please see https://developers.google.com/web/fundamentals/web-app-manifest/#display for options -->
<ManifestDisplay Condition="'$(ManifestDisplay)' == ''">standalone</ManifestDisplay>

<!-- Icons to use if none are supplierd - manifest requires 192x192 and 512x512 -->
<ManifestTemplatePath Condition="'$(ManifestTemplatePath)' == ''">$(MSBuildThisFileDirectory)..\Templates\</ManifestTemplatePath>
<ManifestDefaultIcon192 Condition="'$(ManifestDefaultIcon192)' == ''">$(ManifestTemplatePath)default-icon-192x192.png</ManifestDefaultIcon192>
<ManifestDefaultIcon512 Condition="'$(ManifestDefaultIcon512)' == ''">$(ManifestTemplatePath)default-icon-512x512.png</ManifestDefaultIcon512>
</PropertyGroup>



<!-- Find required icons @ 192x192 and 512x512 -->
<ItemGroup>
<ImageFiles Include="$(ServiceWorkerPreCacheImageFiles);" />
<IconFiles192 Include="$(WWWRoot)**\*icon*192*.*;">
<Size>192x192</Size>
</IconFiles192>
<IconFiles512 Include="$(WWWRoot)**\*icon*512*.*;">
<Size>512x512</Size>
</IconFiles512>
</ItemGroup>

<!-- Use defualt icons if none were provided as they are required for PWA -->
<Copy Condition="'@(IconFiles192)' == ''"
SourceFiles="$(ManifestDefaultIcon192)"
DestinationFolder="$(WWWRoot)"/>
<Copy Condition="'@(IconFiles512)' == ''"
SourceFiles="$(ManifestDefaultIcon512)"
DestinationFolder="$(WWWRoot)"/>

<!-- Now we should definitely have the icons we need -->
<ItemGroup>
<IconFiles Include="$(WWWRoot)**\*icon*192*.*;">
<Size>192x192</Size>
</IconFiles>
<IconFiles Include="$(WWWRoot)**\*icon*512*.*;">
<Size>512x512</Size>
</IconFiles>
<ManifestText Include="{
&quot;short_name&quot;: &quot;$(ManifestShortName)&quot;,
&quot;name&quot;: &quot;$(ManifestLongName)&quot;,
&quot;start_url&quot;: &quot;$(ManifestBaseUrl)&quot;,
&quot;display&quot;: &quot;$(ManifestDisplay)&quot;,
"/>
<ManifestText Include="%20%20&quot;icons&quot;: ["/>
<ManifestText Include="@(IconFiles-> ' {
&quot;src&quot;:&quot;$(ManifestBaseUrl)%(RecursiveDir)%(Filename)%(Extension)&quot;,
&quot;type&quot;:&quot;image/%(Extension)&quot;,
&quot;sizes&quot;:&quot;%(Size)&quot;
}'->Replace('/.','/')->Replace('\','/'),',%0D%0A');%20%20];}"/>
</ItemGroup>

<!-- Write the manifest -->
<WriteLinesToFile File="$(WWWRoot)$(ManifestFileName)" Overwrite="true" Lines="@(ManifestText);" />

<!-- Add manifest to index.html -->
<PropertyGroup>
<IndexFile>$(WWWRoot)$(ServiceWorkerIndexUrl)</IndexFile>
<IndexLines>$([System.IO.File]::ReadAllText($(IndexFile)))</IndexLines>
</PropertyGroup>

<Message Importance="high" Text="Adding manifest to $(IndexFile)"
Condition="'$(IndexLines.Contains(rel=&quot;manifest&quot;))'=='false'"/>

<WriteLinesToFile
File="$(IndexFile)"
Overwrite="true"
Lines="$(IndexLines.Replace('&lt;/head&gt;',' &lt;link href=&quot;/$(ManifestFileName)&quot; rel=&quot;manifest&quot;/&gt;%0D%0A&lt;/head&gt;'))"
Condition="'$(IndexLines.Contains(rel=&quot;manifest&quot;))'=='false'"/>
</Target>
</Project>
Loading

0 comments on commit edc3bf8

Please sign in to comment.