Progressive Web Apps
für moderne Cross-Platform-Lösungen mit Blazor
Christian Liebel Patrick Jahr
@christianliebel @jahr_patrick
Consultant Consultant
Slide 2
Slide 2 text
Feel free to ask questions anytime!
Your instructors
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Patrick Jahr Christian Liebel
Slide 3
Slide 3 text
08:30–10:00 Block 1
10:00–10:30 Break
10:30–12:00 Block 2
12:00–13:00 Break
13:00–14:30 Block 3
14:30–15:00 Break
15:00–16:30 Block 4
Timetable
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 4
Slide 4 text
Proposal
08:30–10:00 Block 1
10:00–10:15 Break
10:15–12:00 Block 2
12:00–12:45 Break
12:45–14:30 Block 3
14:30–14:45 Break
14:45–15:45 Block 4
Timetable
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 5
Slide 5 text
Things NOT to expect
- Blueprint for PWA
development
- No AuthN/AuthZ
- No 1:1 support
Things To Expect
- Extensive/up-to-date insights
into PWA and Project Fugu
- A productivity app use case
that works on your desktop &
smartphone
- Lots of fun
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 6
Slide 6 text
https://paint.js.org
– Productivity app
– Draw images
– Lots of actions & tools
– Installable
– Read/save files
– Copy/paste images
from/to clipboard
– Share files to other apps
– Register for file extensions
Demo Use Case
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 7
Slide 7 text
(Workshop Edition)
– Productivity app
– Draw images
– Lots of actions & tools
– Installable
– Read/save files
– Copy/paste images
from/to clipboard
– Share files to other apps
– Register for file extensions
Demo Use Case
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 8
Slide 8 text
Setup complete?
(.NET 6 SDK, Visual Studio 2022, Chrome or Edge, Git)
Setup (1/2)
LAB
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 9
Slide 9 text
git clone https://github.com/thinktecture/basta-
2022-pwa-blazor.git
git checkout feature/demo
Setup (2/2)
LAB
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 10
Slide 10 text
Paint PWA Capabilities
Progressive
Enhancement
Agenda
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 11
Slide 11 text
Paint PWA Capabilities
Progressive
Enhancement
Agenda
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 12
Slide 12 text
Canvas
– Plain bitmap for the web
– Cross-platform, hardware-
accelerated graphics
operations
– Supports different contexts
(2D, 3D: WebGL, WebGL 2.0)
– Supported on all evergreen
browsers and on IE 9+
Paint
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 13
Slide 13 text
Canvas
Add a canvas element to Index.razor:
Query the canvas element in Index.razor.cs:
private Canvas? _canvas;
Paint
EX #1
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 14
Slide 14 text
Canvas 2D Context
fillRect(x, y, width, height)
strokeRect(x, y, width, height)
beginPath()
moveTo(x, y)
lineTo(x, y)
fill()
stroke()
Paint
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 15
Slide 15 text
Canvas 2D Context
Get the 2D context and prepare the canvas in Index.razor.cs in the
method OnAfterRenderAsync(bool firstRender):
await using var context = await _canvas!.GetContext2DAsync();
await context.FillStyleAsync("white");
await context.FillRectAsync(0, 0, 600, 480);
await context.FillStyleAsync("black");
Paint
EX #2
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 16
Slide 16 text
Low-latency Rendering
Paint
Web pages need to synchronize
with the DOM on graphics updates
causing latencies that can make
drawing difficult
Low-latency rendering skips
syncing with the DOM with can lead
to a more natural experience
Supported on Chrome (Chrome OS
and Windows only)
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 17
Slide 17 text
Low-latency Rendering
Opt-in to low-latency rendering (Index.razor.cs):
await using var context = await
_canvas!.GetContext2DAsync(desynchronized: true);
Paint
EX #3
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 18
Slide 18 text
Pointer Events
Paint
Users nowadays use different
input methods, cross-platform
apps should cover all of them
Pointer Events offer an
abstract interface to catch all
input methods (pointerdown,
pointermove, pointerup)
event.offsetX/event.offsetY
contain the pointer’s position
relative to the listener
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 19
Slide 19 text
Pointer Events
Add event listeners (Index.razor):
Paint
EX #4
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 20
Slide 20 text
Pointer Events
Add event listeners methods (Index.razor.cs):
private async void OnPointerMove(PointerEventArgs args)
{
var currentPoint = new Point
{
X = (int)Math.Floor(args.OffsetX),
Y = (int)Math.Floor(args.OffsetY)
};
await context.FillRectAsync(currentPoint.X, currentPoint.Y, 2, 2);
}
Paint
EX #4
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 21
Slide 21 text
Pointer Events
Add event listeners methods (Index.razor.cs):
private async void OnPointerDown(PointerEventArgs args)
{
if (_module != null && _canvas!.AdditionalAttributes.TryGetValue("id", out var id))
{
await _module.InvokeVoidAsync("registerEvents", id, _selfReference);
}
_previousPoint = new Point
{
X = (int)Math.Floor(args.OffsetX),
Y = (int)Math.Floor(args.OffsetY)
};
}
Paint
EX #4
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 22
Slide 22 text
Bresenham Line Algorithm
The user may move faster than
the input can be processed
For this case, we need to
remember the previous point
and interpolate the points in
between
The Bresenham line algorithm
calculates the missing pixels
between two given points
Paint
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 23
Slide 23 text
Bresenham Line Algorithm
Update the method OnPointerMove() in Index.razor.cs:
if (_previousPoint != null)
{
var currentPoint = new Point
{
X = (int)Math.Floor(args.OffsetX),
Y = (int)Math.Floor(args.OffsetY)
};
var points = _paintService.BrensenhamLine(_previousPoint.Value, currentPoint);
await using var context = await _canvas.GetContext2DAsync();
foreach (var point in points)
{
await context.FillRectAsync(point.X, point.Y, 2, 2);
}
_previousPoint = currentPoint;
}
Paint
EX #5
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 24
Slide 24 text
Color Selection
For this demo, we will only
implement the brush tool. However,
we want to bring in some color.
A simple method to implement a
color selection is to use the HTML
color-type input element that
shows the native color picker:
Paint
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 25
Slide 25 text
Color Selection
1. In Index.razor, add the following input to the node:
2. In Index.razor.cs, add the following code in the method
OnColorChange():
await using var context = await _canvas!.GetContext2DAsync();
await context.FillStyleAsync(args.Value?.ToString());
Paint
EX #6
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 26
Slide 26 text
Paint PWA Capabilities
Progressive
Enhancement
Agenda
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 27
Slide 27 text
Responsive Linkable Discoverable Installable App-like
Connectivity
Independent
Fresh Safe Re-engageable Progressive
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 28
Slide 28 text
Web App
Manifest
Service
Worker
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 29
Slide 29 text
Web App Manifest
Distinguishes Web Apps from
Websites
JSON-based file containing
metadata for apps only
Apps can be identified by search
engines, app store providers, etc.
PWA
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 30
Slide 30 text
manifest.webmanifest
{
"short_name": "Paint",
"name": "Paint Workshop",
"theme_color": "white",
"icons": [{
"src": "icon.png",
"sizes": "512x512"
}],
"start_url": "./",
"display": "standalone",
"shortcuts": [/* … */]
}
PWA
Names
Icons
Display Mode
Shortcuts
Start URL
Theme color (status bar/window bar)
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 31
Slide 31 text
Manifest Display Modes
PWA
browser minimal-ui standalone fullscreen
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 32
Slide 32 text
Manifest Icon Purposes
(any)
any context (e.g. app icon)
monochrome
different color requirements
(at risk)
maskable
user agent masks icon as required
PWA
Safe Zone
Windows iOS Android
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 33
Slide 33 text
Blazor Support
The Blazor PWA template adds
a web app manifest and
service worker support
Progressive Web Apps
für moderne Cross-Platform-Lösungen mit Blazor
PWA
Slide 34
Slide 34 text
Web App Manifest
1. Update the file wwwroot/manifest.json and set:
a) name and short_name to values of your choice
b) theme_color to #000080 and background_color to #808080
2. In index.html, set theme_color to #000080 as well.
3. Run dotnet run
4. Test manifest in DevTools: F12 > Application > Manifest
PWA
EX #7
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 35
Slide 35 text
Manifest Shortcuts
PWA
Secondary entrypoints for your
application (e.g., home screen
quick actions, jump lists, …)
Static definition in Web App
Manifest (dynamic API may
follow in the future)
Supported by Google Chrome
for Android and Edge for
Windows
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 36
Slide 36 text
Web App Manifest
1. In wwwroot/manifest.json, add (at least) the following shortcut:
"shortcuts": [{
"name": "About Paint",
"short_name": "About",
"description": "Show information about Paint",
"url": "./",
"icons": [{ "src": "icon-512.png", "sizes": "512x512" }]
}],
2. Test in DevTools: F12 > Application > Manifest
PWA
EX #8
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 37
Slide 37 text
Web App Manifest – Installability Criteria
Web App is not already installed
User clicked the page at least once and had it open for at least 30
seconds (at any time)
Includes a Web App Manifest that has short_name or name, at least a
192px and 512px icon, a start_url and a display mode of fullscreen,
standalone or minimal-ui
Served over HTTPS
Has a registered service worker with a fetch event handler
https://web.dev/install-criteria/#criteria
PWA
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 38
Slide 38 text
Service Worker
JavaScript snippet executed in an
own thread, registered by the website
Acts as a controller, proxy, or
interceptor
Has a cache to store responses (for
offline availability and performance)
Can wake up even when the website
is closed and perform background
tasks (e.g., push notifications or sync)
PWA
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 39
Slide 39 text
Service Worker
PWA
Service
Worker
Internet
Website
HTML/JS
Cache
fetch
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 40
Slide 40 text
Blazor Service Worker
The Blazor PWA template
includes a custom service
worker implementation
All Blazor assets are precached
by default
Service Worker behavior can
be modified (e.g., for push)
à maximum flexibility
PWA
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 41
Slide 41 text
Service Worker
1. Start application with dotnet run or with Visual Studio
2. Test in DevTools: F12 > Application > Service Worker
3. Install the app: Address Bar > Install
PWA
EX #9
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 42
Slide 42 text
Push Notifications
Just as native apps, PWAs can
receive push notifications
Combination of two technologies:
Web Notifications and Push API
Supported by Chrome, Edge,
Firefox
Support coming to Safari for
macOS with Ventura, iOS and
iPadOS in 2023
Progressive Web Apps
für moderne Cross-Platform-Lösungen mit Blazor
PWA
Slide 43
Slide 43 text
Service Worker Debugging
More information on installed
service workers can be found on
• about://serviceworker-
internals (Google Chrome)
• about:serviceworkers
(Mozilla Firefox)
PWA
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 44
Slide 44 text
Service Worker Debugging
PWA
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 45
Slide 45 text
Lighthouse
PWA
Auditing tool by Google,
integrated in Chrome DevTools
Automatically checks
performance metrics, PWA
support, accessibility, SEO and
other best practices and gives
tips on how to improve
Can simulate mobile devices
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 46
Slide 46 text
Lighthouse
1. Make sure only one tab/window of your PWA is open
2. Open DevTools: F12 > Lighthouse
3. Make sure to select at least the “Progressive Web App” category
4. Click “Generate report”
PWA
EX #10
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 47
Slide 47 text
Paint PWA Capabilities
Progressive
Enhancement
Agenda
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 48
Slide 48 text
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 49
Slide 49 text
Project Fugu
Capabilities
»Let’s bring the web
back – API by API«
Thomas Steiner, Google
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 50
Slide 50 text
Capabilities
Contacts
Picker
Screen Wake
Lock API
File System
Access API
Shape
Detection API
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 51
Slide 51 text
Capabilities
https://goo.gle/fugu-api-tracker
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 52
Slide 52 text
Fugu Process
– Write an Explainer (https://github.com/WICG/native-file-
system/blob/master/EXPLAINER.md)
– Discuss capability with developers, browser vendors, standard orgs
– Iterate
– Compile a design document
– W3C TAG Review (https://github.com/w3ctag/design-
reviews/issues/390)
– Formal spec within Web Incubator Community Group (WICG,
https://wicg.github.io/native-file-system/)
Capabilities
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 53
Slide 53 text
Fugu Process
– Implementation in Chromium
– Launches behind a flag (about://flags/#enable-experimental-web-
platform-features)
– Origin Trial (https://developers.chrome.com/origintrials/)
– Transfer to W3C Working Group + Recommendation?
Capabilities
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 54
Slide 54 text
Browser
Capabilities
navigator.share({ url: 'http://example.com' });
ShareIntent DataTransferManager
…
NSSharingServicePicker
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 55
Slide 55 text
File System Access API
Some applications heavily rely
on working with files (e.g.
Visual Studio Code, Adobe
Photoshop, …)
File System Access API allows
you to open, save and override
files and directories
Supported by Chromium-
based browsers on desktop
Capabilities
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 56
Slide 56 text
File System Access API
1. Add the following buttons to the bar in Index.razor (before the color input):
Open
Save
Copy
Paste
Share
Capabilities
EX #11
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 57
Slide 57 text
File System Access API
2. Add the following lines at the top of Index.razor.cs:
private static FilePickerAcceptType[] _acceptTypes = new
FilePickerAcceptType[]
{
new FilePickerAcceptType
{
Accept = new Dictionary {
{ "image/png", new[] {".png" } }
},
Description = "PNG files"
}
};
Capabilities
EX #11
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 58
Slide 58 text
File System Access API
3. Add the following lines at the top of Index.razor.cs:
private SaveFilePickerOptionsStartInWellKnownDirectory _savePickerOptions =
new SaveFilePickerOptionsStartInWellKnownDirectory
{
StartIn = WellKnownDirectory.Pictures,
Types = _acceptTypes
};
Capabilities
EX #11
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 59
Slide 59 text
File System Access API
4. Add the following lines in the method SaveLocalFile() of Index.razor.cs:
if (_fileHandle == null)
{
_fileHandle = await _fileSystemAccessService
.ShowSaveFilePickerAsync(_savePickerOptions);
}
Capabilities
EX #11
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 60
Slide 60 text
File System Access API
5. Add the following lines in the method SaveLocalFile() of Index.razor.cs:
var writeable = await _fileHandle.CreateWritableAsync();
var image = await _imageService.GetImageDataAsync("canvas");
await writeable.WriteAsync(image);
await writeable.CloseAsync();
await _fileHandle.JSReference.DisposeAsync();
_fileHandle = null;
Capabilities
EX #11
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 61
Slide 61 text
File System Access API
1. Add the following lines at the top of Index.razor.cs:
private readonly OpenFilePickerOptionsStartInWellKnownDirectory
_filePickerOptions = new OpenFilePickerOptionsStartInWellKnownDirectory
{
Multiple = false,
StartIn = WellKnownDirectory.Pictures,
Types = _acceptTypes
};
Capabilities
EX #12
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 62
Slide 62 text
File System Access API
2. Add the following code int the method OpenLocalFile() of Index.razor.cs:
try
{
var fileHandles = await
_fileSystemAccessService.ShowOpenFilePickerAsync(_filePickerOptions);
_fileHandle = fileHandles.Single();
}
catch (JSException ex)
{
Console.WriteLine(ex);
}
Capabilities
EX #12
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 63
Slide 63 text
File System Access API
3. Add the following code int the method OpenLocalFile() of Index.razor.cs:
finally
{
if (_fileHandle is not null)
{
var file = await _fileHandle.GetFileAsync();
await _imageService.OpenFileAccessAsync(file.JSReference);
await using var context = await _canvas!.GetContext2DAsync();
await context.DrawImageAsync("image", 0, 0);
}
}
Capabilities
EX #12
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 64
Slide 64 text
Async Clipboard API
Allows reading from/writing to
the clipboard in an
asynchronous manner (UI won’t
freeze during long-running
operations)
Reading from the clipboard
requires user consent first
(privacy!)
Supported by Chromium-
based browsers and Safari
Capabilities
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 65
Slide 65 text
Async Clipboard API
Add the following code in the method Copy() of Index.razor.cs:
var imagePromise = _asyncClipboardService.GetObjectReference(
_module!, "getCanvasBlob", "canvas");
var clipboardItem = new ClipboardItem(
new Dictionary
{
{ "image/png", imagePromise }
});
await _asyncClipboardService.WriteAsync(
new[] { clipboardItem }
);
Capabilities
EX #13
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 66
Slide 66 text
Async Clipboard API
Add the following code in the method Paste() of Index.razor.cs:
var clipboardItems = await _asyncClipboardService.ReadAsync();
var pngItem = clipboardItems
.FirstOrDefault(c => c.Types.Contains("image/png"));
if (pngItem is not null)
{
var blob = await pngItem.GetTypeAsync("image/png");
await _imageService.OpenFileAccessAsync(blob);
await using var context = await _canvas!.GetContext2DAsync();
await context.DrawImageAsync("image", 0, 0);
}
Capabilities
EX #14
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 67
Slide 67 text
Web Share API
Allows sharing a title, URL, text, or
files
API can only be invoked as a
result of a user action (i.e. a click
or keypress)
Supported by Chrome on
Windows and Chrome OS, Edge,
Safari
Capabilities
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 68
Slide 68 text
Web Share API
Add the following code in the share() method in the Index.razor.cs:
var fileReference = await _imageService.GenerateFileReferenceAsync(
await _canvas!.ToDataURLAsync());
await _shareService.ShareAsync(
new WebShareDataModel
{
Files = new[] { fileReference }
});
Capabilities
EX #15
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 69
Slide 69 text
File System Handling API
Register your PWA as a
handler for file extensions
Requires installing the
application first
Declare supported extensions
in Web App Manifest and add
imperative code to your
application logic
Capabilities
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 70
Slide 70 text
File System Handling API
1. Add the following property to your manifest (wwwroot/manifest.json):
"file_handlers": [{
"action": "./",
"accept": {
"image/png": [".png"]
}
}]
Capabilities
EX #16
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 71
Slide 71 text
File System Handling API
2. Add the following code to the Index.razor.js file at row 23:
if ('launchQueue' in window) {
window.launchQueue.setConsumer(async params => {
const [handle] = params.files;
if (handle) {
const file = await handle.getFile();
await createImageElement(file);
component.invokeMethodAsync('DrawImageAsync');
}
});
}
Capabilities
EX #16
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 72
Slide 72 text
File System Handling API
3. Add the following code to method OnAfterRenderAsync in the Index.razor.cs file:
_selfReference = DotNetObjectReference.Create(this);
if (_module == null)
{
_module = await JS.InvokeAsync("import", "./Pages/Index.razor.js");
}
await _module.InvokeVoidAsync("initializeLaunchQueue", _selfReference);
Capabilities
EX #16
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 73
Slide 73 text
File System Handling API
4. Add the following code to the method DrawImageAsync in the Index.razor.cs file:
[JSInvokable]
public async Task DrawImageAsync()
{
await using var context = await _canvas!.GetContext2DAsync();
await context.DrawImageAsync("image", 0, 0);
}
Capabilities
EX #16
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 74
Slide 74 text
Summary
- Project Fugu helps the web to become more and more capable
- Project Fugu APIs could bring many more app experiences to the web
(IDEs, productivity apps, etc.)
- But: Web is threatened by alternative approaches and platforms,
support for modern Web API varies from platform to platform
- You can make a difference!
- File bugs in browser engine bugtrackers
- File Fugu requests: https://goo.gle/new-fugu-request
Capabilities
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 75
Slide 75 text
Paint PWA Capabilities
Progressive
Enhancement
Agenda
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 76
Slide 76 text
Overview
Use available interfaces and functions of
a system (opposite of Graceful
Degradation)
Users with modern, feature-rich
browsers get a better experience
Apps are available on older browsers, but
with limited functionality
Concept: Browser feature support should
grow over time—thereby more users can
enjoy an increasing number of features
Progressive Enhancement
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 77
Slide 77 text
Overview
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register(…)
.then(() => /* … */);
}
In JavaScript: check whether an API/feature is available. If yes—use it!
Otherwise:
1. Disable the functionality
2. Fall back to an alternative API (if available)
Progressive Enhancement
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 78
Slide 78 text
Disabling unsupported features
In Index.razor.cs, hide the buttons in case the respective API does not exist, e.g.:
_fileSystemAccessSupported = await _fileSystemAccessService.IsSupported();
And hide the buttons which are not supported in the Index.razor, e.g.:
@if(_fileSystemAccessSupported) {
Open
Save
} else {
Download
}
Progressive Enhancement
EX #17
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 79
Slide 79 text
Disabling unsupported features
1. Copy: await _asyncClipboardService.IsSupportedAsync();
2. Paste: await _asyncClipboardService.IsSupportedAsync();
3. Share: await _shareService.IsSupportedAsync();
Progressive Enhancement
EX #17
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 80
Slide 80 text
Disabling unsupported features
Add the following code to the method OnInitializedAsync in the Index.razor.cs file:
_fileSystemAccessSupported = await _fileSystemAccessService.IsSupported();
_clipboardApiSupported = await _asyncClipboardService.IsSupportedAsync();
_shareApiSupported = await _shareService.IsSupportedAsync();
Progressive Enhancement
EX #17
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 81
Slide 81 text
Disabling unsupported features
Replace the following code to the Index.razor file:
Copy
Paste
Share
Progressive Enhancement
EX #17
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 82
Slide 82 text
Providing an alternative implementation
If the feature are not supported, fall back to the following code for the SaveFile()
Method:
await _imageService.DownloadAsync(await _canvas!.ToDataURLAsync());
Progressive Enhancement
EX #18
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 83
Slide 83 text
Providing an alternative implementation
If the feature are not supported, fall back to the following code for the OpenFile()
Method:
await using var context = await _canvas!.GetContext2DAsync();
await _imageService.OpenAsync(args.File.OpenReadStream(1024 * 15 * 1000));
await context.DrawImageAsync("image", 0, 0);
Progressive Enhancement
EX #19
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 84
Slide 84 text
Deployment
Electron/Capacitor
JS
HTML
CSS
.ipa
.exe .app ELF
.apk .appx
Single-Page
Application
Capacitor
Electron
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 85
Slide 85 text
(Simplified)
Store Deployments
https://example.com
.appx
.apk
Server
Microsoft
Store
Play
Store
Source
Files
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 86
Slide 86 text
Run app on your device
https://ngrok.com/download
ngrok http {{port}}
EX #20
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 87
Slide 87 text
Q&A
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 88
Slide 88 text
Progressive Web Apps
für moderne Cross-Platform-Lösungen mit Blazor
Spotify
https://open.spotify.com/
Slide 89
Slide 89 text
Progressive Web Apps
für moderne Cross-Platform-Lösungen mit Blazor
VS Code
https://vscode.dev/
Slide 90
Slide 90 text
Progressive Web Apps
für moderne Cross-Platform-Lösungen mit Blazor
Photoshop
https://creativecloud.adobe.com/cc/photoshop
Slide 91
Slide 91 text
Implement great productivity, enterprise, … applications that run just fine
in the browser
Improve the experience by allowing users to install your app and run it
offline
Add Fugu capabilities for an even deeper integration with the operating
system
Ensure that users of older or less powerful browsers can still use the app
Let’s build great apps for the web!
Summary
für moderne Cross-Platform-Lösungen mit Blazor
Progressive Web Apps
Slide 92
Slide 92 text
Thank you
for your kind attention!
Christian Liebel
@christianliebel
[email protected]
https://www.thinktecture.com/ueber-uns/karriere/
Patrick Jahr
@jahr_patrick
[email protected]