Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
55 changes: 33 additions & 22 deletions packages/@ionic/cli/src/commands/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ interface StartWizardApp {
email: string;
theme: string;
ip: string;
appIcon: string;
appSplash: string;
utm: { [key: string]: string };
}

Expand Down Expand Up @@ -197,6 +199,14 @@ Use the ${input('--type')} option to start projects using older versions of Ioni

await this.startIdConvert(startId as string);

const appIconBuffer = data.appIcon ?
Buffer.from(data.appIcon.replace(/^data:image\/\w+;base64,/, ''), 'base64') :
undefined;

const splashBuffer = data.appSplash ?
Buffer.from(data.appSplash.replace(/^data:image\/\w+;base64,/, ''), 'base64') :
undefined;

this.schema = {
cloned: false,
name: data.name,
Expand All @@ -206,6 +216,8 @@ Use the ${input('--type')} option to start projects using older versions of Ioni
projectDir,
packageId: data['package-id'],
appflowId: undefined,
appIcon: appIconBuffer,
splash: splashBuffer,
themeColor: data.theme,
};
}
Expand Down Expand Up @@ -538,24 +550,18 @@ Use the ${input('--type')} option to start projects using older versions of Ioni
}
}

if (options['capacitor'] === null && !options['cordova']) {
const confirm = await this.env.prompt({
type: 'confirm',
name: 'confirm',
message: 'Integrate your new app with Capacitor to target native iOS and Android?',
default: false,
});

if (confirm) {
options['capacitor'] = true;
}
}

if (options['capacitor']) {
if (!options['cordova']) {
await runCommand(runinfo, ['integrations', 'enable', 'capacitor', '--quiet', '--', this.schema.name, packageId ? packageId : 'io.ionic.starter']);
}

await this.project.personalize({ name: this.schema.name, projectId, packageId, themeColor: this.schema.themeColor });
await this.project.personalize({
name: this.schema.name,
projectId,
packageId,
appIcon: this.schema.appIcon,
splash: this.schema.splash,
themeColor: this.schema.themeColor,
});

this.env.log.nl();
}
Expand Down Expand Up @@ -622,7 +628,7 @@ Use the ${input('--type')} option to start projects using older versions of Ioni

this.env.log.nl();

await this.showNextSteps(projectDir, this.schema.cloned, linkConfirmed);
await this.showNextSteps(projectDir, this.schema.cloned, linkConfirmed, !options['cordova']);
}

async checkForExisting(projectDir: string) {
Expand Down Expand Up @@ -728,18 +734,23 @@ Use the ${input('--type')} option to start projects using older versions of Ioni
tasks.end();
}

async showNextSteps(projectDir: string, cloned: boolean, linkConfirmed: boolean) {
async showNextSteps(projectDir: string, cloned: boolean, linkConfirmed: boolean, isCapacitor: boolean) {
const cordovaResCommand = isCapacitor ? 'cordova-res --skip-config --copy' : 'cordova-res';
const steps = [
`Go to your ${cloned ? 'cloned' : 'newly created'} project: ${input(`cd ${prettyPath(projectDir)}`)}`,
`Run ${input('ionic serve')} within the app directory to see your app`,
`Build features and components: ${strong('https://ion.link/scaffolding-docs')}`,
`Run your app on a hardware or virtual device: ${strong('https://ion.link/running-docs')}`,
`Go to your ${cloned ? 'cloned' : 'new'} project: ${input(`cd ${prettyPath(projectDir)}`)}`,
`Run ${input('ionic serve')} within the app directory to see your app in the browser`,
isCapacitor ?
`Run ${input('ionic capacitor add')} to add a native iOS or Android project using Capacitor` :
`Run ${input('ionic cordova platform add')} to add a native iOS or Android project using Cordova`,
`Generate your app icon and splash screens using ${input(cordovaResCommand)}`,
`Explore the Ionic docs for components, tutorials, and more: ${strong('https://ion.link/docs')}`,
`Building an enterprise app? Ionic has Enterprise Support and Features: ${strong('https://ion.link/enterprise-edition')}`,
];

if (linkConfirmed) {
steps.push(`Push your code to Ionic Appflow to perform real-time updates, and more: ${input('git push ionic master')}`);
}

this.env.log.info(`${strong('Next Steps')}:\n${steps.map(s => `- ${s}`).join('\n')}`);
this.env.log.msg(`${strong('Your Ionic app is ready! Follow these next steps')}:\n${steps.map(s => ` - ${s}`).join('\n')}`);
}
}
2 changes: 2 additions & 0 deletions packages/@ionic/cli/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ export interface ProjectPersonalizationDetails {
version?: string;
description?: string;
themeColor?: string;
appIcon?: Buffer;
splash?: Buffer;
}

export interface IProjectConfig {
Expand Down
28 changes: 24 additions & 4 deletions packages/@ionic/cli/src/lib/project/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { PromptModule } from '@ionic/cli-framework-prompts';
import { resolveValue } from '@ionic/cli-framework/utils/fn';
import { TTY_WIDTH, prettyPath, wordWrap } from '@ionic/cli-framework/utils/format';
import { ERROR_INVALID_PACKAGE_JSON, compileNodeModulesPaths, isValidPackageName, readPackageJsonFile } from '@ionic/cli-framework/utils/node';
import { findBaseDirectory, readFile, writeFile, writeJson } from '@ionic/utils-fs';
import { ensureDir, findBaseDirectory, readFile, writeFile, writeJson } from '@ionic/utils-fs';
import * as Debug from 'debug';
import * as lodash from 'lodash';
import * as path from 'path';
Expand Down Expand Up @@ -89,7 +89,7 @@ export class ProjectDetails {
async getIdFromPathMatch(config: IMultiProjectConfig): Promise<string | undefined> {
const { ctx } = this.e;

for (const [ key, value ] of lodash.entries(config.projects)) {
for (const [key, value] of lodash.entries(config.projects)) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I must have vscode auto formatting for some reason

const id = key;

if (value && value.root) {
Expand Down Expand Up @@ -569,7 +569,7 @@ export abstract class Project implements IProject {
}

async personalize(details: ProjectPersonalizationDetails): Promise<void> {
const { name, projectId, description, version, themeColor } = details;
const { name, projectId, description, version, themeColor, appIcon, splash } = details;

this.config.set('name', name);

Expand All @@ -585,14 +585,18 @@ export abstract class Project implements IProject {
await this.setPrimaryTheme(themeColor);
}

if (appIcon && splash) {
await this.setAppResources(appIcon, splash);
}

const integrations = await this.getIntegrations();

await Promise.all(integrations.map(async i => i.personalize(details)));
}

// Empty to avoid sub-classes having to implement
// tslint:disable-next-line:no-empty
async setPrimaryTheme(_themeColor: string): Promise<void> {}
async setPrimaryTheme(_themeColor: string): Promise<void> { }

async writeThemeColor(variablesPath: string, themeColor: string): Promise<void> {
const light = new Color(themeColor);
Expand Down Expand Up @@ -683,6 +687,22 @@ export abstract class Project implements IProject {
}
}

async setAppResources(appIcon: Buffer, splash: Buffer) {
const resourcesDir = path.join(this.directory, 'resources');
const iconPath = path.join(resourcesDir, 'icon.png');
const splashPath = path.join(resourcesDir, 'splash.png');

try {
await ensureDir(resourcesDir);

await writeFile(iconPath, appIcon);
await writeFile(splashPath, splash);
} catch (e) {
const { log } = this.e;
log.error(`Unable to find or create the resources directory. Skipping icon generation: ${e}`);
}
}

async registerAilments(registry: IAilmentRegistry): Promise<void> {
const ailments = await import('../doctor/ailments');
const deps = { ...this.e, project: this };
Expand Down
2 changes: 2 additions & 0 deletions packages/@ionic/cli/src/lib/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export interface NewAppSchema extends BaseAppSchema {
type: ProjectType;
template: string;
themeColor?: string;
appIcon?: Buffer;
splash?: Buffer;
}

export interface ClonedAppSchema extends BaseAppSchema {
Expand Down