Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for fullscreen display mode #212

Merged
merged 5 commits into from
Jun 30, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion packages/cli/src/lib/cmds/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import * as fs from 'fs';
import Color = require('color');
import * as inquirer from 'inquirer';
import {Config, JdkHelper, KeyTool, Log, TwaGenerator, TwaManifest, util} from '@bubblewrap/core';
import {validateColor, validateKeyPassword, validateUrl, notEmpty} from '../inputHelpers';
import {validateColor, validateDisplayMode, validateKeyPassword, validateUrl,
notEmpty} from '../inputHelpers';
import {ParsedArgs} from 'minimist';
import {APP_NAME} from '../constants';

Expand Down Expand Up @@ -49,6 +50,12 @@ async function confirmTwaConfig(twaManifest: TwaManifest): Promise<TwaManifest>
message: 'Name to be shown on the Android Launcher:',
default: twaManifest.launcherName,
validate: async (input): Promise<boolean> => notEmpty(input, 'Launcher name'),
}, {
name: 'display',
type: 'input',
christianliebel marked this conversation as resolved.
Show resolved Hide resolved
message: 'Display mode to be used:',
default: twaManifest.display,
validate: validateDisplayMode,
}, {
name: 'themeColor',
type: 'input',
Expand Down Expand Up @@ -131,6 +138,7 @@ async function confirmTwaConfig(twaManifest: TwaManifest): Promise<TwaManifest>
twaManifest.host = result.host;
twaManifest.name = result.name;
twaManifest.launcherName = result.launcherName;
twaManifest.display = result.display;
twaManifest.themeColor = new Color(result.themeColor);
twaManifest.backgroundColor = new Color(result.backgroundColor);
twaManifest.startUrl = result.startUrl;
Expand Down
8 changes: 8 additions & 0 deletions packages/cli/src/lib/inputHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,11 @@ export async function validateUrl(url: string): Promise<boolean> {
}
return true;
}

export async function validateDisplayMode(displayMode: string): Promise<boolean> {
const validModes = ['browser', 'minimal-ui', 'standalone', 'fullscreen'];
christianliebel marked this conversation as resolved.
Show resolved Hide resolved
if (!validModes.includes(displayMode)) {
throw new Error(`${displayMode} is not a valid display mode (${validModes.join(', ')})`);
}
return true;
}
13 changes: 13 additions & 0 deletions packages/cli/src/spec/inputHelpersSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,17 @@ describe('inputHelpers', () => {
inputHelpers.validateColor('rgb(23, 0 30')).toBeRejectedWithError();
});
});

describe('#validateDisplayMode', () => {
it('returns true for valid colors', async () => {
expect(await inputHelpers.validateDisplayMode('browser'));
expect(await inputHelpers.validateDisplayMode('minimal-ui'));
expect(await inputHelpers.validateDisplayMode('standalone'));
expect(await inputHelpers.validateDisplayMode('fullscreen'));
});

it('throws Error for invalid display modes', async () => {
await expectAsync(inputHelpers.validateColor('bogus')).toBeRejectedWithError();
christianliebel marked this conversation as resolved.
Show resolved Hide resolved
});
});
});
6 changes: 6 additions & 0 deletions packages/core/src/lib/TwaManifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const MIN_NOTIFICATION_ICON_SIZE = 48;
// Default values used on the Twa Manifest
const DEFAULT_SPLASHSCREEN_FADEOUT_DURATION = 300;
const DEFAULT_APP_NAME = 'My TWA';
const DEFAULT_DISPLAY_MODE = 'standalone';
const DEFAULT_THEME_COLOR = '#FFFFFF';
const DEFAULT_NAVIGATION_COLOR = '#000000';
const DEFAULT_BACKGROUND_COLOR = '#FFFFFF';
Expand Down Expand Up @@ -72,6 +73,7 @@ export class ShortcutInfo {
* hostName: '<%= host %>', // The domain being opened in the TWA.
* launchUrl: '<%= startUrl %>', // The start path for the TWA. Must be relative to the domain.
* name: '<%= name %>', // The name shown on the Android Launcher.
* display: '<%= display %>', // The display mode for the TWA.
* themeColor: '<%= themeColor %>', // The color used for the status bar.
* navigationColor: '<%= themeColor %>', // The color used for the navigation bar.
* backgroundColor: '<%= backgroundColor %>', // The color used for the splash screen background.
Expand All @@ -94,6 +96,7 @@ export class TwaManifest {
host: string;
name: string;
launcherName: string;
display: string;
christianliebel marked this conversation as resolved.
Show resolved Hide resolved
themeColor: Color;
navigationColor: Color;
backgroundColor: Color;
Expand All @@ -118,6 +121,7 @@ export class TwaManifest {
this.host = data.host;
this.name = data.name;
this.launcherName = data.launcherName || data.name; // Older Manifests may not have this field.
this.display = data.display || DEFAULT_DISPLAY_MODE; // Older Manifests may not have this field.
this.themeColor = new Color(data.themeColor);
this.navigationColor = new Color(data.navigationColor);
this.backgroundColor = new Color(data.backgroundColor);
Expand Down Expand Up @@ -254,6 +258,7 @@ export class TwaManifest {
name: webManifest['name'] || webManifest['short_name'] || DEFAULT_APP_NAME,
launcherName: webManifest['short_name'] ||
webManifest['name']?.substring(0, SHORT_NAME_MAX_SIZE) || DEFAULT_APP_NAME,
display: webManifest['display'] || DEFAULT_DISPLAY_MODE,
christianliebel marked this conversation as resolved.
Show resolved Hide resolved
themeColor: webManifest['theme_color'] || DEFAULT_THEME_COLOR,
navigationColor: DEFAULT_NAVIGATION_COLOR,
backgroundColor: webManifest['background_color'] || DEFAULT_BACKGROUND_COLOR,
Expand Down Expand Up @@ -306,6 +311,7 @@ export interface TwaManifestJson {
host: string;
name: string;
launcherName?: string; // Older Manifests may not have this field.
display?: string; // Older Manifests may not have this field.
themeColor: string;
navigationColor: string;
backgroundColor: string;
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/lib/types/WebManifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export interface WebManifestJson {
name?: string;
short_name?: string;
start_url?: string;
display?: string;
christianliebel marked this conversation as resolved.
Show resolved Hide resolved
theme_color?: string;
background_color?: string;
icons?: Array<WebManifestIcon>;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/spec/lib/TwaManifestSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ describe('TwaManifest', () => {
'name': 'PWA Directory',
'short_name': 'PwaDirectory',
'start_url': '/?utm_source=homescreen',
'display': 'standalone',
christianliebel marked this conversation as resolved.
Show resolved Hide resolved
'icons': [{
'src': '/favicons/android-chrome-192x192.png',
'sizes': '192x192',
Expand All @@ -50,6 +51,7 @@ describe('TwaManifest', () => {
expect(twaManifest.packageId).toBe('com.pwa_directory.twa');
expect(twaManifest.name).toBe('PWA Directory');
expect(twaManifest.launcherName).toBe('PwaDirectory');
expect(twaManifest.display).toBe('standalone');
expect(twaManifest.startUrl).toBe('/?utm_source=homescreen');
expect(twaManifest.iconUrl)
.toBe('https://pwa-directory.com/favicons/android-chrome-512x512.png');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@
<meta-data android:name="android.support.customtabs.trusted.FALLBACK_STRATEGY"
android:value="@string/fallbackType" />

<% if (display === 'fullscreen') { %>
<meta-data android:name="android.support.customtabs.trusted.DISPLAY_MODE"
android:value="immersive" />

<% }%>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
Expand Down