diff --git a/Blazor.PWA.MSBuild.Tasks/Blazor.PWA.MSBuild.Tasks.csproj b/Blazor.PWA.MSBuild.Tasks/Blazor.PWA.MSBuild.Tasks.csproj
index 3ca3918..51883d9 100644
--- a/Blazor.PWA.MSBuild.Tasks/Blazor.PWA.MSBuild.Tasks.csproj
+++ b/Blazor.PWA.MSBuild.Tasks/Blazor.PWA.MSBuild.Tasks.csproj
@@ -69,7 +69,9 @@ I will add more network caching strategies, but for now it has just one - cache
+
+
diff --git a/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register-beforeinstallprompt.template.js b/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register-beforeinstallprompt.template.js
new file mode 100644
index 0000000..cca06aa
--- /dev/null
+++ b/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register-beforeinstallprompt.template.js
@@ -0,0 +1,9 @@
+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();
+
+});
diff --git a/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register-installable-banner.template.js b/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register-installable-banner.template.js
index 16ec412..10d5456 100644
--- a/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register-installable-banner.template.js
+++ b/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register-installable-banner.template.js
@@ -6,15 +6,15 @@ function showAddToHomeScreen() {
pwaInstallPrompt.id = 'pwa-install-prompt';
pwaInstallPrompt.style.position = 'absolute';
- pwaInstallPrompt.style.bottom = '1rem';
- pwaInstallPrompt.style.left = '1rem';
- pwaInstallPrompt.style.right = '1rem';
- pwaInstallPrompt.style.padding = '0.3rem';
+ pwaInstallPrompt.style.bottom = '0.1rem';
+ pwaInstallPrompt.style.left = '0.1rem';
+ pwaInstallPrompt.style.right = '0.1rem';
+ pwaInstallPrompt.style.padding = '0.5rem';
pwaInstallPrompt.style.display = 'flex';
pwaInstallPrompt.style.backgroundColor = 'lightslategray';
pwaInstallPrompt.style.color = 'white';
pwaInstallPrompt.style.fontFamily = 'sans-serif';
- pwaInstallPrompt.style.fontSize = '1.2rem';
+ pwaInstallPrompt.style.fontSize = '1.3rem';
pwaInstallPrompt.style.borderRadius = '4px';
pwaInstallButton.style.marginLeft = 'auto';
diff --git a/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register-installable-blazor.template.js b/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register-installable-blazor.template.js
new file mode 100644
index 0000000..205b773
--- /dev/null
+++ b/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register-installable-blazor.template.js
@@ -0,0 +1,17 @@
+
+function showAddToHomeScreen() {
+ DotNet.invokeMethodAsync(blazorAssembly, blazorInstallMethod)
+ .then(function () { }, function (er) { setTimeout(showAddToHomeScreen, 1000); });
+}
+
+window.BlazorPWA = {
+ installPWA: function () {
+ if (window.PWADeferredPrompt) {
+ window.PWADeferredPrompt.prompt();
+ window.PWADeferredPrompt.userChoice
+ .then(function (choiceResult) {
+ window.PWADeferredPrompt = null;
+ });
+ }
+ }
+};
diff --git a/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register.template.js b/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register.template.js
index 4841f70..f107874 100644
--- a/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register.template.js
+++ b/Blazor.PWA.MSBuild.Tasks/Templates/ServiceWorker/sw_register.template.js
@@ -24,12 +24,3 @@
}
});
-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();
-
-});
diff --git a/Blazor.PWA.MSBuild.Tasks/build/BlazorPWA.MSBuild.ServiceWorkerRegister.targets b/Blazor.PWA.MSBuild.Tasks/build/BlazorPWA.MSBuild.ServiceWorkerRegister.targets
index 2f87cee..229734d 100644
--- a/Blazor.PWA.MSBuild.Tasks/build/BlazorPWA.MSBuild.ServiceWorkerRegister.targets
+++ b/Blazor.PWA.MSBuild.Tasks/build/BlazorPWA.MSBuild.ServiceWorkerRegister.targets
@@ -20,17 +20,30 @@
installable-banner$(ServiceWorkerRegisterTemplatePath)sw_register-$(ServiceWorkerRegisterInstallableType).template.js
+
+ beforeinstallprompt
+
+ $(ServiceWorkerRegisterTemplatePath)sw_register-$(ServiceWorkerRegisterBeforeInstallPromptType).template.jsinstalledUpdate available. Reload the page when convenient.
+
+ $(ProjectName)
+
+ PWAInstallable
-
+
const serviceWorkerFileName = '$(ServiceWorkerBaseURL)$(ServiceWorkerFileName)'%3B;
const swInstalledEvent = '$(ServiceWorkerInstalledEvent)'%3B;
const staticCachePrefix = '$(ServiceWorkerCacheName)-v'%3B;
const updateAlertMessage = '$(ServiceWorkerUpdateAlertText)'%3B;
+
+ $(ServiceWorkerRegisterConstants);
+ const blazorAssembly = '$(ServiceWorkerBlazorAssembly)'%3B;
+ const blazorInstallMethod = '$(ServiceWorkerBlazorInstallMethod)'%3B;
+
@@ -45,7 +58,24 @@
+
+
+
+
+
+
+
+
Install this app?
+
+
+}
+```
+This will display a bar at the bottom of the browser, which can be dismissed or clicked.
+
+
+The `code` section has the `JSInvokable` method **InstallPWS** that we called
+earlier from the browser and some supporting code to toggle the display and
+make an interop call back to the browser to trigger the app installation.
+``` C#
+@code
+{
+ [Inject] IJSRuntime JSRuntime { get; set; }
+
+ static bool Installable = false;
+ static Action ml;
+ protected override void OnInitialized()
+ {
+ ml = () => InvokeAsync(StateHasChanged);
+ }
+ [JSInvokable]
+ public static Task InstallPWA()
+ {
+ Installable = true;
+ ml.Invoke();
+ return Task.CompletedTask;
+ }
+ Task InstallClicked(UIMouseEventArgs args)
+ {
+ Installable = false;
+ return JSRuntime.InvokeAsync