Skip to content

Commit

Permalink
feat(web): support for web icons
Browse files Browse the repository at this point in the history
  • Loading branch information
RatakondalaArun committed Jul 8, 2022
1 parent e597498 commit 4a49ff8
Show file tree
Hide file tree
Showing 8 changed files with 583 additions and 25 deletions.
75 changes: 75 additions & 0 deletions lib/abs/icon_generator.dart
@@ -0,0 +1,75 @@
import 'dart:io';

import 'package:flutter_launcher_icons/flutter_launcher_icons_config.dart';
import 'package:flutter_launcher_icons/logger.dart';

///A base class to generate icons
abstract class IconGenerator {
final IconGeneratorContext context;
final String platformName;

IconGenerator(this.context, this.platformName);

/// Creates icons for this platform.
void createIcons();

/// Should return `true` if this platform
/// has all the requirments to create icons.
/// This runs before to [createIcons]
bool validateRequirments();
}

/// Provides easy access to user arguments and configuration
class IconGeneratorContext {
/// Contains configuration from configuration file
final FlutterLauncherIconsConfig config;
final FLILogger logger;
final String? flavor;

IconGeneratorContext({required this.config, this.flavor, required this.logger});

/// Shortcut for `config.webConfig`
WebConfig? get webConfig => config.webConfig;
}

/// Generates Icon for given platforms
void generateIconsFor({
required FlutterLauncherIconsConfig config,
required String? flavor,
required FLILogger logger,
required List<IconGenerator> Function(IconGeneratorContext context) platforms,
}) {
try {
final platformList = platforms(IconGeneratorContext(config: config, logger: logger, flavor: flavor));
if (platformList.isEmpty) {
// ? maybe we can print help
logger.info('No platform provided');
}

for (final platform in platformList) {
final progress = logger.progress('Creating Icons for ${platform.platformName}');
logger.verbose('Validating platform requirments for ${platform.platformName}');
// in case a platform throws an exception it should not effect other platforms
try {
if (!platform.validateRequirments()) {
logger.error('Requirments failed for platform ${platform.platformName}. Skipped');
progress.cancel();
continue;
}
platform.createIcons();
progress.finish(message: 'done', showTiming: true);
} catch (e) {
progress.cancel();
continue;
}
}
} catch (e, st) {
// todo: better error handling
// stacktrace should only print when verbose is turned on
// else a normal help line
logger
..error(e.toString())
..verbose(st);
exit(1);
}
}
10 changes: 10 additions & 0 deletions lib/custom_exceptions.dart
Expand Up @@ -39,3 +39,13 @@ class NoDecoderForImageFormatException implements Exception {
return generateError(this, message);
}
}

class FileNotFoundException implements Exception {
const FileNotFoundException(this.fileName);

final String fileName;
@override
String toString() {
return generateError(this, '$fileName file not found');
}
}
145 changes: 145 additions & 0 deletions lib/flutter_launcher_icons_config.dart
@@ -0,0 +1,145 @@
import 'dart:io';

import 'package:checked_yaml/checked_yaml.dart' as yaml;
import 'package:json_annotation/json_annotation.dart';

import 'constants.dart' as constants;
import 'custom_exceptions.dart';
import 'utils.dart' as utils;

part 'flutter_launcher_icons_config.g.dart';

@JsonSerializable(
anyMap: true,
checked: true,
)
class FlutterLauncherIconsConfig {
/// Generic imagepath
@JsonKey(name: 'image_path')
final String? imagePath;

/// Returns true or path if android config is enabled
final dynamic android; // path or bool

/// Returns true or path if ios config is enabled
final dynamic ios; // path or bool

/// Image path specific to android
@JsonKey(name: 'image_path_android')
final String? imagePathAndroid;

/// Image path specific to ios
@JsonKey(name: 'image_path_ios')
final String? imagePathIOS;

/// android adaptive icon foreground image
@JsonKey(name: 'adaptive_icon_foreground')
final String? adaptiveIconForeground;

/// android adaptive_icon_background image
@JsonKey(name: 'adaptive_icon_background')
final String? adaptiveIconBackground;

/// Web platform config
@JsonKey(name: 'web')
final WebConfig? webConfig;

const FlutterLauncherIconsConfig({
this.imagePath,
this.android = false,
this.ios = false,
this.imagePathAndroid,
this.imagePathIOS,
this.adaptiveIconForeground,
this.adaptiveIconBackground,
this.webConfig,
});

factory FlutterLauncherIconsConfig.fromJson(Map json) => _$FlutterLauncherIconsConfigFromJson(json);

/// Loads flutter launcher icons configs from given [filePath]
static FlutterLauncherIconsConfig? loadConfigFromPath(String filePath) {
final configFile = File(filePath);
if (!configFile.existsSync()) {
return null;
}
final configContent = configFile.readAsStringSync();
try {
return yaml.checkedYamlDecode<FlutterLauncherIconsConfig>(
configContent,
(json) => FlutterLauncherIconsConfig.fromJson(json!['flutter_icons']),
);
} on yaml.ParsedYamlException catch (e) {
throw InvalidConfigException(e.formattedMessage);
} catch (e) {
rethrow;
}
}

/// Loads flutter launcher icons config from `pubspec.yaml` file
static FlutterLauncherIconsConfig? loadConfigFromPubSpec() {
try {
final pubspecFile = File(constants.pubspecFilePath);
if (!pubspecFile.existsSync()) {
return null;
}
final pubspecContent = pubspecFile.readAsStringSync();
return yaml.checkedYamlDecode<FlutterLauncherIconsConfig?>(
pubspecContent,
(json) {
if (json!['flutter_icons'] == null) {
return null;
}
return FlutterLauncherIconsConfig.fromJson(json['flutter_icons']);
},
);
} on yaml.ParsedYamlException catch (e) {
throw InvalidConfigException(e.formattedMessage);
} catch (e) {
rethrow;
}
}

static FlutterLauncherIconsConfig? loadConfigFromFlavor(String flavor) {
return FlutterLauncherIconsConfig.loadConfigFromPath(utils.flavorConfigFile(flavor));
}

Map<String, dynamic> toJson() => _$FlutterLauncherIconsConfigToJson(this);

@override
String toString() => 'FlutterLauncherIconsConfig: ${toJson()}';
}

@JsonSerializable(
anyMap: true,
checked: true,
)
class WebConfig {
final bool generate;

/// Image path for web
@JsonKey(name: 'image_path')
final String? imagePath;

/// manifest.json's background_color
@JsonKey(name: 'background_color')
final String? backgroundColor;

/// manifest.json's theme_color
@JsonKey(name: 'theme_color')
final String? themeColor;

const WebConfig({
this.generate = false,
this.imagePath,
this.backgroundColor,
this.themeColor,
});

factory WebConfig.fromJson(Map json) => _$WebConfigFromJson(json);

Map<String, dynamic> toJson() => _$WebConfigToJson(this);

@override
String toString() => 'WebConfig: ${toJson()}';
}
78 changes: 78 additions & 0 deletions lib/flutter_launcher_icons_config.g.dart

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

0 comments on commit 4a49ff8

Please sign in to comment.