Skip to content

Commit d341285

Browse files
Merge pull request #3435 from NativeScript/IIIvanov/Assets-Generation
feat: introduce assets generation
2 parents ce71e70 + dd2c26d commit d341285

22 files changed

+1328
-24
lines changed

.vscode/launch.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
// "args": [ "run", "android", "--path", "cliapp"]
2323
// "args": [ "debug", "android", "--path", "cliapp"]
2424
// "args": [ "livesync", "android", "--path", "cliapp"]
25-
// "args": [ "livesync", "android", "--watch", "--path", "cliapp"]
25+
// "args": [ "livesync", "android", "--watch", "--path", "cliapp"],
26+
// "args": [ "resources", "generate", "icons", "./test/image-generation-test.png", "--path", "cliapp" ],
27+
// "args": [ "resources", "generate", "splashes", "./test/image-generation-test.png", "--path", "cliapp", "--background", "#8000ff" ],
2628
},
2729
{
2830
// in case you want to debug a single test, modify it's code to be `it.only(...` instead of `it(...`

PublicAPI.md

+115-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ const tns = require("nativescript");
1414
* [projectDataService](#projectdataservice)
1515
* [getProjectData](#getprojectdata)
1616
* [getProjectDataFromContent](#getprojectdatafromcontent)
17+
* [getNsConfigDefaultContent](#getnsconfigdefaultcontent)
18+
* [getAssetsStructure](#getassetsstructure)
19+
* [getIOSAssetsStructure](#getiosassetsstructure)
20+
* [getAndroidAssetsStructure](#getandroidassetsstructure)
1721
* [extensibilityService](#extensibilityservice)
1822
* [installExtension](#installextension)
1923
* [uninstallExtension](#uninstallextension)
@@ -41,7 +45,9 @@ const tns = require("nativescript");
4145
* [analyticsSettingsService](#analyticsSettingsService)
4246
* [getClientId](#getClientId)
4347
* [constants](#constants)
44-
48+
* [assetsGenerationService](#assetsgenerationservice)
49+
* [generateIcons](#generateicons)
50+
* [generateSplashScreens](#generatesplashscreens)
4551

4652
## Module projectService
4753

@@ -199,6 +205,66 @@ Returns the default content of "nsconfig.json" merged with the properties provid
199205
getNsConfigDefaultContent(data?: Object): string
200206
```
201207
208+
### getAssetsStructure
209+
Gives information about the whole assets structure for both iOS and Android. For each of the platforms, the returned object will contain icons, splashBackgrounds, splashCenterImages and splashImages (only for iOS).
210+
* Definition:
211+
```TypeScript
212+
/**
213+
* Gives information about the whole assets structure for both iOS and Android.
214+
* For each of the platforms, the returned object will contain icons, splashBackgrounds, splashCenterImages and splashImages (only for iOS).
215+
* @param {IProjectDir} opts Object with a single property - projectDir. This is the root directory where NativeScript project is located.
216+
* @returns {Promise<IAssetsStructure>} An object describing the current asset structure.
217+
*/
218+
getAssetsStructure(opts: IProjectDir): Promise<IAssetsStructure>;
219+
```
220+
221+
* Usage:
222+
```JavaScript
223+
tns.projectDataService.getAssetsStructure({ projectDir: "/Users/username/myNativeScriptProject" })
224+
.then(assetsStructure => console.log(`The current assets structure is ${JSON.stringify(assetsStructure, null, 2)}.`))
225+
.catch(err => console.log("Failed to get assets structure."));
226+
```
227+
228+
### getIOSAssetsStructure
229+
Gives information about the assets structure for iOS .The returned object will contain icons, splashBackgrounds, splashCenterImages and splashImages.
230+
* Definition:
231+
```TypeScript
232+
/**
233+
* Gives information about the whole assets structure for iOS.
234+
* The returned object will contain icons, splashBackgrounds, splashCenterImages and splashImages.
235+
* @param {IProjectDir} opts Object with a single property - projectDir. This is the root directory where NativeScript project is located.
236+
* @returns {Promise<IAssetGroup>} An object describing the current asset structure for iOS.
237+
*/
238+
getIOSAssetsStructure(opts: IProjectDir): Promise<IAssetGroup>;
239+
```
240+
241+
* Usage:
242+
```JavaScript
243+
tns.projectDataService.getIOSAssetsStructure({ projectDir: "/Users/username/myNativeScriptProject" })
244+
.then(assetsStructure => console.log(`The current assets structure for iOS is ${JSON.stringify(assetsStructure, null, 2)}.`))
245+
.catch(err => console.log("Failed to get assets structure."));
246+
```
247+
248+
### getAndroidAssetsStructure
249+
Gives information about the assets structure for Android .The returned object will contain icons, splashBackgrounds and splashCenterImages.
250+
* Definition:
251+
```TypeScript
252+
/**
253+
* Gives information about the whole assets structure for Android.
254+
* The returned object will contain icons, splashBackgrounds and splashCenterImages.
255+
* @param {IProjectDir} opts Object with a single property - projectDir. This is the root directory where NativeScript project is located.
256+
* @returns {Promise<IAssetGroup>} An object describing the current asset structure for Android.
257+
*/
258+
getAndroidAssetsStructure(opts: IProjectDir): Promise<IAssetGroup>;
259+
```
260+
261+
* Usage:
262+
```JavaScript
263+
tns.projectDataService.getAndroidAssetsStructure({ projectDir: "/Users/username/myNativeScriptProject" })
264+
.then(assetsStructure => console.log(`The current assets structure for Android is ${JSON.stringify(assetsStructure, null, 2)}.`))
265+
.catch(err => console.log("Failed to get assets structure."));
266+
```
267+
202268
## extensibilityService
203269
`extensibilityService` module gives access to methods for working with CLI's extensions - list, install, uninstall, load them. The extensions add new functionality to CLI, so once an extension is loaded, all methods added to it's public API are accessible directly through CLI when it is used as a library. Extensions may also add new commands, so they are accessible through command line when using NativeScript CLI.
204270
@@ -1013,6 +1079,54 @@ tns.analyticsSettingsService.getPlaygroundInfo("/my/project/path")
10131079
## constants
10141080
Contains various constants related to NativeScript.
10151081
1082+
## assetsGenerationService
1083+
`assetsGenerationService` module allows generation of assets - icons and splashes.
1084+
1085+
### generateIcons
1086+
The `generateIcons` method generates icons for specified platform (or both iOS and Android in case platform is not specified) and places them on correct location in the specified project.
1087+
1088+
* Definition:
1089+
```TypeScript
1090+
/**
1091+
* Generate icons for iOS and Android
1092+
* @param {IResourceGenerationData} iconsGenerationData Provides the data needed for icons generation
1093+
* @returns {Promise<void>}
1094+
*/
1095+
generateIcons({ imagePath: string, projectDir: string, platform?: string }): Promise<void>;
1096+
```
1097+
1098+
* Usage:
1099+
```JavaScript
1100+
tns.assetsGenerationService.generateIcons({ projectDir: "/Users/username/myNativeScriptProject", imagePath: "/Users/username/image.png" })
1101+
.then(() => {
1102+
console.log("Successfully generated icons");
1103+
});
1104+
```
1105+
1106+
1107+
### generateSplashScreens
1108+
The `generateSplashScreens` method generates icons for specified platform (or both iOS and Android in case platform is not specified) and places them on correct location in the specified project.
1109+
1110+
* Definition:
1111+
```TypeScript
1112+
/**
1113+
* Generate splash screens for iOS and Android
1114+
* @param {ISplashesGenerationData} splashesGenerationData Provides the data needed for splash screens generation
1115+
* @returns {Promise<void>}
1116+
*/
1117+
generateSplashScreens({ imagePath: string, projectDir: string, platform?: string, background?: string }): Promise<void>;
1118+
```
1119+
1120+
* Usage:
1121+
```JavaScript
1122+
tns.assetsGenerationService.generateSplashScreens({ projectDir: "/Users/username/myNativeScriptProject", imagePath: "/Users/username/image.png", background: "blue" })
1123+
.then(() => {
1124+
console.log("Successfully generated splash screens");
1125+
});
1126+
```
1127+
1128+
1129+
10161130
## How to add a new method to Public API
10171131
CLI is designed as command line tool and when it is used as a library, it does not give you access to all of the methods. This is mainly implementation detail. Most of the CLI's code is created to work in command line, not as a library, so before adding method to public API, most probably it will require some modification.
10181132
For example the `$options` injected module contains information about all `--` options passed on the terminal. When the CLI is used as a library, the options are not populated. Before adding method to public API, make sure its implementation does not rely on `$options`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<% if (isJekyll) { %>---
2+
title: tns resources generate icons
3+
position: 11
4+
---<% } %>
5+
# tns resources generate icons
6+
7+
Usage | Synopsis
8+
------|-------
9+
`$ tns resources generate icons <Path to image>` | Generate all icons for Android and iOS based on the specified image.
10+
11+
Generates all icons for Android and iOS platforms and places the generated images in the correct directories under `App_Resources/<platform>` directory.
12+
13+
### Attributes
14+
* `<Path to image>` is a valid path to an image that will be used to generate all icons.
15+
16+
<% if(isHtml) { %>
17+
### Related Commands
18+
19+
Command | Description
20+
----------|----------
21+
[install](../install.html) | Installs all platforms and dependencies described in the `package.json` file in the current directory.
22+
[platform add](../platform-add.html) | Configures the current project to target the selected platform.
23+
[platform remove](../platform-remove.html) | Removes the selected platform from the platforms that the project currently targets.
24+
[platform](../platform.html) | Lists all platforms that the project currently targets.
25+
[prepare](../prepare.html) | Copies common and relevant platform-specific content from the app directory to the subdirectory for the selected target platform in the platforms directory.
26+
[resources update](resources-update.md) | Updates the `App_Resources/Android` internal folder structure to conform to that of an Android Studio project.
27+
[resources generate splashes](resources-generate-splashes.md) | Generates splashscreens for Android and iOS.
28+
<% } %>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<% if (isJekyll) { %>---
2+
title: tns resources generate splashes
3+
position: 12
4+
---<% } %>
5+
# tns resources generate splashes
6+
7+
Usage | Synopsis
8+
------|-------
9+
`$ tns resources generate splashes <Path to image> [<background>]` | Generate all splashscreens for Android and iOS based on the specified image.
10+
11+
Generates all icons for Android and iOS platforms and places the generated images in the correct directories under `App_Resources/<platform>` directory.
12+
13+
### Attributes
14+
* `<Path to image>` is a valid path to an image that will be used to generate all splashscreens.
15+
* `<background>` is a valid path to an image that will be used as a background of the splashscreen. Defaults to white in case it is not specified.
16+
17+
<% if(isHtml) { %>
18+
### Related Commands
19+
20+
Command | Description
21+
----------|----------
22+
[install](../install.html) | Installs all platforms and dependencies described in the `package.json` file in the current directory.
23+
[platform add](../platform-add.html) | Configures the current project to target the selected platform.
24+
[platform remove](../platform-remove.html) | Removes the selected platform from the platforms that the project currently targets.
25+
[platform](../platform.html) | Lists all platforms that the project currently targets.
26+
[prepare](../prepare.html) | Copies common and relevant platform-specific content from the app directory to the subdirectory for the selected target platform in the platforms directory.
27+
[resources update](resources-update.md) | Updates the `App_Resources/Android` internal folder structure to conform to that of an Android Studio project.
28+
[resources generate icons](resources-generate-icons.md) | Generates icons for Android and iOS.
29+
<% } %>

docs/man_pages/project/configuration/resources/resources-update.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<% if (isJekyll) { %>---
22
title: tns resources update
3-
position: 9
3+
position: 10
44
---<% } %>
5-
#tns resources update
5+
# tns resources update
66
==========
77

88
Usage | Synopsis
@@ -11,7 +11,7 @@ Usage | Synopsis
1111
`$ tns resources update android` | Updates the App_Resources/Android's folder structure.
1212

1313
Updates the App_Resources/<platform>'s internal folder structure to conform to that of an Android Studio project. Android resource files and directories will be located at the following paths:
14-
- `drawable-*`, `values`, `raw`, etc. can be found at `App_Resources/Android/src/main/res`
14+
- `drawable-*`, `values`, `raw`, etc. can be found at `App_Resources/Android/src/main/res`
1515
- `AndroidManifest.xml` can be found at `App_Resources/Android/src/main/AndroidManifest.xml`
1616
- Java source files can be dropped in at `App_Resources/Android/src/main/java` after creating the proper package subdirectory structure
1717
- Additional arbitrary assets can be dropped in at `App_Resources/Android/src/main/assets`

lib/bootstrap.ts

+4
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,7 @@ $injector.require("terminalSpinnerService", "./services/terminal-spinner-service
161161
$injector.require('playgroundService', './services/playground-service');
162162
$injector.require("platformEnvironmentRequirements", "./services/platform-environment-requirements");
163163
$injector.require("nativescriptCloudExtensionService", "./services/nativescript-cloud-extension-service");
164+
165+
$injector.requireCommand("resources|generate|icons", "./commands/generate-assets");
166+
$injector.requireCommand("resources|generate|splashes", "./commands/generate-assets");
167+
$injector.requirePublic("assetsGenerationService", "./services/assets-generation/assets-generation-service");

lib/commands/generate-assets.ts

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
export abstract class GenerateCommandBase implements ICommand {
2+
public allowedParameters: ICommandParameter[] = [this.$stringParameterBuilder.createMandatoryParameter("You have to provide path to image to generate other images based on it.")];
3+
4+
constructor(protected $options: IOptions,
5+
protected $injector: IInjector,
6+
protected $projectData: IProjectData,
7+
protected $stringParameterBuilder: IStringParameterBuilder,
8+
protected $assetsGenerationService: IAssetsGenerationService) {
9+
this.$projectData.initializeProjectData();
10+
}
11+
12+
public async execute(args: string[]): Promise<void> {
13+
const [ imagePath ] = args;
14+
await this.generate(imagePath, this.$options.background);
15+
}
16+
17+
protected abstract generate(imagePath: string, background?: string): Promise<void>;
18+
}
19+
20+
export class GenerateIconsCommand extends GenerateCommandBase implements ICommand {
21+
constructor(protected $options: IOptions,
22+
$injector: IInjector,
23+
protected $projectData: IProjectData,
24+
protected $stringParameterBuilder: IStringParameterBuilder,
25+
$assetsGenerationService: IAssetsGenerationService) {
26+
super($options, $injector, $projectData, $stringParameterBuilder, $assetsGenerationService);
27+
}
28+
29+
protected async generate(imagePath: string, background?: string): Promise<void> {
30+
await this.$assetsGenerationService.generateIcons({ imagePath, projectDir: this.$projectData.projectDir });
31+
}
32+
}
33+
34+
$injector.registerCommand("resources|generate|icons", GenerateIconsCommand);
35+
36+
export class GenerateSplashScreensCommand extends GenerateCommandBase implements ICommand {
37+
constructor(protected $options: IOptions,
38+
$injector: IInjector,
39+
protected $projectData: IProjectData,
40+
protected $stringParameterBuilder: IStringParameterBuilder,
41+
$assetsGenerationService: IAssetsGenerationService) {
42+
super($options, $injector, $projectData, $stringParameterBuilder, $assetsGenerationService);
43+
}
44+
45+
protected async generate(imagePath: string, background?: string): Promise<void> {
46+
await this.$assetsGenerationService.generateSplashScreens({ imagePath, background, projectDir: this.$projectData.projectDir });
47+
}
48+
}
49+
50+
$injector.registerCommand("resources|generate|splashes", GenerateSplashScreensCommand);

lib/constants.ts

+15
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,18 @@ export const NATIVESCRIPT_CLOUD_EXTENSION_NAME = "nativescript-cloud";
148148
* Used in ProjectDataService to concatenate the names of the properties inside nativescript key of package.json.
149149
*/
150150
export const NATIVESCRIPT_PROPS_INTERNAL_DELIMITER = "**|__**";
151+
export const CLI_RESOURCES_DIR_NAME = "resources";
152+
153+
export class AssetConstants {
154+
public static iOSResourcesFileName = "Contents.json";
155+
public static iOSAssetsDirName = "Assets.xcassets";
156+
public static iOSIconsDirName = "AppIcon.appiconset";
157+
public static iOSSplashBackgroundsDirName = "LaunchScreen.AspectFill.imageset";
158+
public static iOSSplashCenterImagesDirName = "LaunchScreen.Center.imageset";
159+
public static iOSSplashImagesDirName = "LaunchImage.launchimage";
160+
161+
public static imageDefinitionsFileName = "image-definitions.json";
162+
public static assets = "assets";
163+
164+
public static sizeDelimiter = "x";
165+
}

lib/declarations.d.ts

+47-2
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,7 @@ interface IOptions extends ICommonOptions, IBundleString, IPlatformTemplate, IEm
463463
liveEdit: boolean;
464464
chrome: boolean;
465465
inspector: boolean; // the counterpart to --chrome
466+
background: string;
466467
}
467468

468469
interface IEnvOptions {
@@ -570,7 +571,7 @@ interface IAndroidToolsInfo {
570571
*/
571572
validateAndroidHomeEnvVariable(options?: IAndroidToolsInfoOptions): boolean;
572573

573-
/**
574+
/**
574575
* Validates target sdk
575576
* @param {IAndroidToolsInfoOptions} options @optional Defines if the warning messages should treated as error.
576577
* @returns {boolean} True if there are detected issues, false otherwise
@@ -790,7 +791,51 @@ interface IBundleValidatorHelper {
790791
interface INativescriptCloudExtensionService {
791792
/**
792793
* Installs nativescript-cloud extension
793-
* @return {Promise<IExtensionData>} returns the extension data
794+
* @return {Promise<IExtensionData>} returns the extension data
794795
*/
795796
install(): Promise<IExtensionData>;
796797
}
798+
799+
/**
800+
* Describes the basic data needed for resource generation
801+
*/
802+
interface IResourceGenerationData extends IProjectDir {
803+
/**
804+
* @param {string} imagePath Path to the image that will be used for generation
805+
*/
806+
imagePath: string,
807+
808+
/**
809+
* @param {string} platform Specify for which platform to generate assets. If not defined will generate for all platforms
810+
*/
811+
platform?: string
812+
}
813+
814+
/**
815+
* Describes the data needed for splash screens generation
816+
*/
817+
interface ISplashesGenerationData extends IResourceGenerationData {
818+
/**
819+
* @param {string} background Background color that will be used for background. Defaults to #FFFFFF
820+
*/
821+
background?: string
822+
}
823+
824+
/**
825+
* Describes service used for assets generation
826+
*/
827+
interface IAssetsGenerationService {
828+
/**
829+
* Generate icons for iOS and Android
830+
* @param {IResourceGenerationData} iconsGenerationData Provides the data needed for icons generation
831+
* @returns {Promise<void>}
832+
*/
833+
generateIcons(iconsGenerationData: IResourceGenerationData): Promise<void>;
834+
835+
/**
836+
* Generate splash screens for iOS and Android
837+
* @param {ISplashesGenerationData} splashesGenerationData Provides the data needed for splash screens generation
838+
* @returns {Promise<void>}
839+
*/
840+
generateSplashScreens(splashesGenerationData: ISplashesGenerationData): Promise<void>;
841+
}

0 commit comments

Comments
 (0)