Skip to content

Commit

Permalink
Staging (#4646)
Browse files Browse the repository at this point in the history
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Beth Pan <xupa@microsoft.com>
Co-authored-by: Gleb Khmyznikov <gleb.khmyznikov@gmail.com>
Co-authored-by: Jaylyn Barbee <jaylyn.1b@gmail.com>
Co-authored-by: Jaylyn Barbee <51131738+Jaylyn-Barbee@users.noreply.github.com>
Co-authored-by: Nikola Metulev <nmetulev@users.noreply.github.com>
Co-authored-by: Mara'ah Lee <maraahlee@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Adolf Daniel <10156724+adolfdaniel@users.noreply.github.com>
Co-authored-by: Justin Willis (HE / HIM) <juwillis@microsoft.com>
Co-authored-by: Zach Teutsch <88554871+zateutsch@users.noreply.github.com>
Co-authored-by: vipul-bhojwani <67650372+vipul-bhojwani@users.noreply.github.com>
Co-authored-by: Amrutha Srinivasan <amrutha.srinivasan95@gmail.com>
Co-authored-by: Federico Navarrete <darklord.navarrete@gmail.com>
Co-authored-by: Toby Liu <ybot1122@gmail.com>
Co-authored-by: microsoft-github-policy-service[bot] <77245923+microsoft-github-policy-service[bot]@users.noreply.github.com>
Co-authored-by: Amrutha Srinivasan <amsrin@microsoft.com>
Co-authored-by: Jonas Thelemann <e-mail@jonas-thelemann.de>
Co-authored-by: Siraj Chokshi <19193347+SirajChokshi@users.noreply.github.com>
Co-authored-by: Thomas Peißl <7underlines@gmail.com>
Co-authored-by: Migush <Migushthe2nd@users.noreply.github.com>
Co-authored-by: Abdullhakim Sami Alshanqity <132011567+abdullhakim-sami@users.noreply.github.com>
Co-authored-by: mecmep <69386369+mecmep@users.noreply.github.com>
  • Loading branch information
1 parent 233c0c4 commit ab2bbca
Show file tree
Hide file tree
Showing 19 changed files with 145 additions and 38 deletions.
7 changes: 7 additions & 0 deletions .github/workflows/pwabuilder-main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ jobs:

generate_release:
runs-on: ubuntu-latest
permissions:
actions: read
contents: write
deployments: write
packages: write
pull-requests: read

name: Generate Release including changelog
steps:
- uses: "marvinpinto/action-automatic-releases@latest"
Expand Down
1 change: 1 addition & 0 deletions apps/blog/src/includes/author-profile.njk
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
.tagline {
margin: 0;
text-align: center;
}
.ap-twitter {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Announcing the App Capabilities Card
excerpt: Introducing the new App Capabilities section of the PWABuilder Report Card page
description: Introducing the new App Capabilities section of the PWABuilder Report Card page
date: 2023-10-16
updatedDate: 2023-10-16
updatedDate: 2024-01-26
trending: true
featured: true
image: posts/announcing-app-capabilities/hero.png
Expand All @@ -15,7 +15,7 @@ author:
twitter: jaylynsatwork
title: Software Engineer
tagline: East Coast based Software Engineer who loves to cooking, gaming, and playing volleyball!
image: /author_images/justin_image.jpg
image: /author_images/jaylyn_image.jpg
tags:
- post
- PWABuilder.com
Expand Down
7 changes: 5 additions & 2 deletions apps/blog/src/posts/goodnotes-showcase/goodnotes-showcase.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ title: How GoodNotes uses web APIs to create a great PWA for Windows
excerpt: Let's explore how GoodNotes uses web APIs to make their PWA great on Windows, especially on devices that support pen and touch input.
description: In this blog post, we will explore how GoodNotes uses web APIs to make their PWA great on Windows, especially on devices that support pen and touch input.
date: 2024-01-24
updatedDate: 2024-01-24
updatedDate: 2024-01-25
trending: true
featured: true
image: posts/goodnotes-showcase/person-drawing.jpg
isPost: true
backUrl: '/'
author:
name: Justin Willis
title: PWABuilder SWE
twitter: Justinwillis96
title: Software Engineer
tagline: When i'm not developing PWAs you can find me hiking, gaming or playing with my pets!
image: /author_images/justin_image.jpg
tags:
- post
- PWA
Expand Down
88 changes: 88 additions & 0 deletions apps/blog/src/posts/macos-pwa-install/macos-pwa-install.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
layout: post
title: Web Apps on macOS Sonoma got a proper install experience
excerpt: How we detected Web Apps availability on macOS platform.
description: How we enabled Sonoma's Web Apps support for PWA Install component.
date: 2024-02-01
updatedDate: 2024-02-01
trending: true
featured: true
image: posts/macos-pwa-install/pic-1-wide.jpg
isPost: true
backUrl: '/'
author:
name: Gleb Khmyznikov
twitter: khmyznikov
title: Software Engineer
image: /author_images/gleb_image.jpg
tagline: Eastern Europe based Software Engineer who loves PC hardware, gaming handhelds, classic cars and web technologies.
tags:
- post
- macOS
- Web Apps
---

<figure>
<video preload="none" controls poster="/posts/macos-pwa-install/pic-1-wide.jpg">
<source src="/posts/macos-pwa-install/video.webm" type="video/webm">
</video>
<figcaption>Installing PWA's on macOS Safari</figcaption>
</figure>

### Backstory

With the release of macOS Sonoma, we are excited to see Apple making a big step forward in supporting Web Apps in general and Progressive Web Applications specifically. This is great news for developers and users alike, as it means that PWAs will be more accessible on Mac than ever before.

Unfortunately, there is no built-in browsers experiences for prompting PWA installation on Safari. This is where the [pwa-install](https://github.com/khmyznikov/pwa-install) component comes in. It's a simple, lightweight, framework agnostic web-component that provides a native-like installation experience for PWAs on iOS/iPadOS and now on macOS Sonoma. It's easy to use and works with any PWA or simple Web App, so you can get started right away.

![PWA Install Instructions](/posts/macos-pwa-install/pic-3.jpg)

Why does easy installation matter? Progressive Web Applications offer a lot of flexibility and user engagement. One of the main selling points is their app-like presence on your device. However, not every browser has made it easy to install them. This update is set to make the installation of PWAs feel more native, especially for users on macOS Safari.

### Implementation

But how it was archived? Safari on macOS Sonoma supports the Web App Manifest, which is a JSON file that describes the Web App metadata. This includes the app's name, description, icons, and more. The pwa-install component uses this information to create a native-like installation experience for PWAs on iOS/iPadOS and macOS Sonoma.

But here's a catch: Safari on macOS doesn't provide any API to detect Web Apps availability. So, we used a workaround to detect Web Apps availability on macOS platform.

[Here's how it works](https://github.com/khmyznikov/pwa-install/blob/cf73d0c382fd87aa6b5a5cc40f0474150efe3487/src/utils.ts#L24):

```js
static isAppleDesktop(): boolean {
// check if it's a mac
const userAgent = navigator.userAgent.toLowerCase();
if (navigator.maxTouchPoints || !userAgent.match(/macintosh/))
return false;
// check safari version >= 17
const version = /version\/(\d{2})\./.exec(userAgent)
if (!version || !version[1] || !(parseInt(version[1]) >= 17))
return false;
// hacky way to detect Sonoma
const audioCheck = document.createElement('audio').canPlayType('audio/wav; codecs="1"') ? true : false;
const webGLCheck = new OffscreenCanvas(1, 1).getContext('webgl') ? true : false;

return audioCheck && webGLCheck;
}
```
When we combine the user agent and Sonoma specific Safari feature detections, we can detect Web Apps availability on macOS platform. We run previous and current macOS version with latest Safari 17 side by side and with help of [tool like this](https://browserleaks.com/features), we were able to detect the difference we can use.

### Installation

This isn't just about Safari on macOS. The component keeps the user experience consistent no matter the device.

| &nbsp;&nbsp;iOS&nbsp;&nbsp; | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Android |
| --- | --- | --- |
|![iOS install prompt](/posts/macos-pwa-install/pic-4.jpg)|![iOS install instructions](/posts/macos-pwa-install/pic-5.jpg)|![Android Gallery](/posts/macos-pwa-install/pic-6.jpg)|

![Chrome Prompt](/posts/macos-pwa-install/pic-7.jpg)

Adding this component to your project is simple. The [readme](https://github.com/khmyznikov/pwa-install?tab=readme-ov-file#install) includes a one-line npm install command, import instructions, and basic HTML for adding the component to an app. Here is a live [demo](https://khmyznikov.com/pwa-install/) to show you exactly how it should look and work.
Most modern frameworks can use the component as a web component. React polyfill is included.

What's coming soon for PWA installation? Samsung Internet and Firefox Mobile are the next browsers to get the pwa-install component. This will make it even easier for users on Android devices to install PWAs from their favorite browsers.

### Conclusion

The pwa-install component aims to improve the install process for PWAs, with the most recent update making the experience feel more native for Safari users on the new macOS Sonoma. Whether you're aiming to reach macOS, iOS, or wider audiences, this component can play for you a vital role in creating a seamless PWA installation experience.

Jump into the [demo](https://khmyznikov.com/pwa-install/) to see the new features for yourself. If you like the progress, feel free to [contribute](https://github.com/khmyznikov/pwa-install) features or translations through pull requests.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/blog/src/posts/macos-pwa-install/pic-1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/blog/src/posts/macos-pwa-install/pic-2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/blog/src/posts/macos-pwa-install/pic-3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/blog/src/posts/macos-pwa-install/pic-4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/blog/src/posts/macos-pwa-install/pic-5.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/blog/src/posts/macos-pwa-install/pic-6.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/blog/src/posts/macos-pwa-install/pic-7.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added apps/blog/src/posts/macos-pwa-install/video.webm
Binary file not shown.
16 changes: 8 additions & 8 deletions apps/pwabuilder/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/pwabuilder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"rimraf": "^3.0.2",
"ts-node": "^10.1.0",
"tslib": "^2.1.0",
"typescript": "^4.6.3",
"typescript": "^5.3.3",
"vite": "^2.9.0"
},
"prettier": {
Expand Down
40 changes: 26 additions & 14 deletions apps/pwabuilder/src/script/pages/app-report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export class AppReport extends LitElement {
@state() showConfirmationModal: boolean = false;
@state() thingToAdd: string = "";
@state() retestConfirmed: boolean = false;
@state() readdDenied: boolean = false;

@state() createdManifest: boolean = false;
@state() manifestContext: ManifestContext | undefined;
Expand Down Expand Up @@ -2899,6 +2900,29 @@ export class AppReport extends LitElement {
}
}

renderReaddDialog() {
var dialogContent = html`
<p>Have you added your new ${this.thingToAdd} to your site?</p>
<div id="confirmationButtons">
<sl-button @click=${() => this.retest(true)}> Yes </sl-button>
<sl-button @click=${() => this.readdDenied = true}> No </sl-button>
</div>
`

if(this.retestConfirmed) {
dialogContent = html`
<p>Retesting your site now!</p>
`;
}
else if (this.readdDenied) {
dialogContent = html`
<p>Add your new ${this.thingToAdd}, and then we can retest your site. </p>
`;
}

return dialogContent;
}

render() {
return html`
<app-header .page=${"report"}></app-header>
Expand Down Expand Up @@ -3455,20 +3479,8 @@ export class AppReport extends LitElement {
</div>
<sl-dialog class="dialog" ?open=${this.showConfirmationModal} @sl-hide=${() => this.showConfirmationModal = false} noHeader>
${this.retestConfirmed ?
html`
<p>Retesting your site now!</p>
` :
html`
<p>Have you added your new ${this.thingToAdd} to your site?</p>
<div id="confirmationButtons">
<sl-button>No</sl-button>
<sl-button @click=${() => this.retest(true)}>Yes</sl-button>
</div>
`
}
<sl-dialog class="dialog" ?open=${this.showConfirmationModal} @sl-hide=${() => {this.showConfirmationModal = false; this.readdDenied = false;}} noHeader>
${this.renderReaddDialog()}
</sl-dialog>
<share-card
Expand Down
15 changes: 5 additions & 10 deletions apps/pwabuilder/src/script/utils/icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ export function findSuitableIcon(
return null;
}

const iconInfos = isIconInfos(icons) ? icons : icons.map(i => new IconInfo(i));
const exactMatch = iconInfos.find(i => i.isExactMatch(purpose, desiredWidth, desiredHeight, mimeType));
const iconInfos: IconInfo[] = isIconInfos(icons) ? icons : icons.map(i => new IconInfo(i));
const exactMatch: IconInfo | undefined = iconInfos.findLast(i => i.isExactMatch(purpose, desiredWidth, desiredHeight, mimeType));
if (exactMatch) {
return exactMatch.getIcon();
}

var largerMatch = iconInfos.find(i => i.isSuitableIcon(purpose, desiredWidth, desiredHeight, mimeType));
var largerMatch: IconInfo | undefined = iconInfos.findLast(i => i.isSuitableIcon(purpose, desiredWidth, desiredHeight, mimeType));
return largerMatch?.getIcon() || null;
}

/**
* Finds a app icon suitable as a general purpose app icon: idealy, a large, square, PNG icon whose purpose is any.
* Finds a app icon suitable as a general purpose app icon: ideally, a large, square, PNG icon whose purpose is any.
* @param icons The icons in which to find a good primary app icon.
* @returns An icon suitable to use as a general purpose app icon.
*/
Expand All @@ -69,12 +69,7 @@ export function findBestAppIcon(icons: Icon[] | null | undefined): Icon | null {
}

function isIconInfos(icons: Icon[] | IconInfo[]): icons is IconInfo[] {
const firstIcon = icons[0];
if (firstIcon instanceof IconInfo) {
return true;
}

return false;
return ( icons[0] instanceof IconInfo );
}

/**
Expand Down
3 changes: 2 additions & 1 deletion apps/pwabuilder/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"types": [
"node", "vite/client"
],
"sourceMap": true
"sourceMap": true,
"skipLibCheck": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules"]
Expand Down

0 comments on commit ab2bbca

Please sign in to comment.