Skip to content

Commit

Permalink
Merge pull request #374 from fluttercommunity/RatakondalaArun/web-sup…
Browse files Browse the repository at this point in the history
…port

RatakondalaArun/web-support
  • Loading branch information
RatakondalaArun committed Jul 23, 2022
2 parents d2c493d + 3a5822e commit a69a4e9
Show file tree
Hide file tree
Showing 22 changed files with 1,573 additions and 51 deletions.
13 changes: 8 additions & 5 deletions analysis_options.yaml
Expand Up @@ -13,12 +13,13 @@ analyzer:
# Please see https://github.com/flutter/flutter/pull/24528 for details.
sdk_version_async_exported_from_core: ignore
exclude:
- 'bin/cache/**'
- "bin/cache/**"
# the following two are relative to the stocks example and the flutter package respectively
# see https://github.com/dart-lang/sdk/issues/28463
- 'lib/i18n/stock_messages_*.dart'
- 'lib/src/http/**'
- 'example/**'
- "lib/i18n/stock_messages_*.dart"
- "lib/src/http/**"
- "example/**"
- "**/*.g.dart"

linter:
rules:
Expand Down Expand Up @@ -128,7 +129,7 @@ linter:
# - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml
- recursive_getters
- slash_for_doc_comments
- sort_constructors_first
# - sort_constructors_first: vscode's command "dart:sort members" does not follow this
- sort_pub_dependencies
- sort_unnamed_constructors_first
# - super_goes_last # no longer needed w/ Dart 2
Expand Down Expand Up @@ -157,3 +158,5 @@ linter:
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
- valid_regexps
# - void_checks # not yet tested
- public_member_api_docs
- require_trailing_commas
24 changes: 24 additions & 0 deletions flutter_launcher_icons.code-workspace
@@ -0,0 +1,24 @@
{
"folders": [
{
"name": "Flutter Launcher Icons",
"path": "."
}
],
"settings": {
"[dart]": {
"editor.formatOnSave": true,
// "editor.formatOnType": true,
"editor.rulers": [
120
],
"editor.selectionHighlight": false,
"editor.suggest.snippetsPreventQuickSuggestions": false,
"editor.suggestSelection": "first",
"editor.tabCompletion": "onlySnippets",
"editor.wordBasedSuggestions": false,
"files.insertFinalNewline": true
},
"dart.lineLength": 120,
}
}
109 changes: 109 additions & 0 deletions lib/abs/icon_generator.dart
@@ -0,0 +1,109 @@
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 {
/// Contains config
final IconGeneratorContext context;

/// Name of the platform this [IconGenerator] is created for.
final String platformName;

/// Creates a instance of [IconGenerator].
///
/// A [context] is created and provided by [generateIconsFor],
/// [platformName] takes the name of the platform that this [IconGenerator]
/// is implemented for
///
/// Also Refer
/// - [WebIconGenerator] generate icons for web
/// - [generateIconFor] generates icons for given platform
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 validateRequirements();
}

/// Provides easy access to user arguments and configuration
class IconGeneratorContext {
/// Contains configuration from configuration file
final FlutterLauncherIconsConfig config;

/// A logger
final FLILogger logger;

/// Value of `--prefix` flag
final String prefixPath;

/// Value of `--flavor` flag
final String? flavor;

/// Creates an instance of [IconGeneratorContext]
IconGeneratorContext({
required this.config,
required this.logger,
required this.prefixPath,
this.flavor,
});

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

/// Generates Icon for given platforms
void generateIconsFor({
required FlutterLauncherIconsConfig config,
required String? flavor,
required String prefixPath,
required FLILogger logger,
required List<IconGenerator> Function(IconGeneratorContext context) platforms,
}) {
try {
final platformList = platforms(IconGeneratorContext(
config: config,
logger: logger,
prefixPath: prefixPath,
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.validateRequirements()) {
logger.error('Requirments failed for platform ${platform.platformName}. Skipped');
progress.cancel();
continue;
}
platform.createIcons();
progress.finish(message: 'done', showTiming: true);
} catch (e, st) {
progress.cancel();
logger
..error(e.toString())
..verbose(st);
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);
}
}
52 changes: 36 additions & 16 deletions lib/constants.dart
@@ -1,35 +1,55 @@
String androidResFolder(String? flavor) =>
"android/app/src/${flavor ?? 'main'}/res/";
String androidColorsFile(String? flavor) =>
"android/app/src/${flavor ?? 'main'}/res/values/colors.xml";
import 'package:path/path.dart' as path;

/// Relative path to android resource folder
String androidResFolder(String? flavor) => "android/app/src/${flavor ?? 'main'}/res/";

/// Relative path to android colors.xml file
String androidColorsFile(String? flavor) => "android/app/src/${flavor ?? 'main'}/res/values/colors.xml";

const String androidManifestFile = 'android/app/src/main/AndroidManifest.xml';
const String androidGradleFile = 'android/app/build.gradle';
const String androidLocalPropertiesFile = 'android/local.properties';
const String androidFileName = 'ic_launcher.png';
const String androidAdaptiveForegroundFileName = 'ic_launcher_foreground.png';
const String androidAdaptiveBackgroundFileName = 'ic_launcher_background.png';
String androidAdaptiveXmlFolder(String? flavor) =>
androidResFolder(flavor) + 'mipmap-anydpi-v26/';
String androidAdaptiveXmlFolder(String? flavor) => androidResFolder(flavor) + 'mipmap-anydpi-v26/';
const String androidDefaultIconName = 'ic_launcher';

const String iosDefaultIconFolder =
'ios/Runner/Assets.xcassets/AppIcon.appiconset/';
const String iosDefaultIconFolder = 'ios/Runner/Assets.xcassets/AppIcon.appiconset/';
const String iosAssetFolder = 'ios/Runner/Assets.xcassets/';
const String iosConfigFile = 'ios/Runner.xcodeproj/project.pbxproj';
const String iosDefaultIconName = 'Icon-App';

// web
/// favicon.ico size
const int kFaviconSize = 16;

/// Relative web direcotry path
String webDirPath = path.join('web');

/// Relative web icons directory path
String webIconsDirPath = path.join(webDirPath, 'icons');

/// Relative web manifest.json file path
String webManifestFilePath = path.join(webDirPath, 'manifest.json');
// todo: support for other images formats
/// Relative favicon.png path
String webFaviconFilePath = path.join(webDirPath, 'favicon.png');

/// Relative index.html file path
String webIndexFilePath = path.join(webDirPath, 'index.html');

/// Relative pubspec.yaml path
String pubspecFilePath = path.join('pubspec.yaml');

const String errorMissingImagePath =
'Missing "image_path" or "image_path_android" + "image_path_ios" within configuration';
const String errorMissingPlatform =
'No platform specified within config to generate icons for.';
const String errorMissingRegularAndroid =
'Adaptive icon config found but no regular Android config. '
const String errorMissingPlatform = 'No platform specified within config to generate icons for.';
const String errorMissingRegularAndroid = 'Adaptive icon config found but no regular Android config. '
'Below API 26 the regular Android config is required';
const String errorMissingMinSdk =
'Cannot not find minSdk from android/app/build.gradle or android/local.properties'
const String errorMissingMinSdk = 'Cannot not find minSdk from android/app/build.gradle or android/local.properties'
'Specify minSdk in either android/app/build.gradle or android/local.properties';
const String errorIncorrectIconName =
'The icon name must contain only lowercase a-z, 0-9, or underscore: '
const String errorIncorrectIconName = 'The icon name must contain only lowercase a-z, 0-9, or underscore: '
'E.g. "ic_my_new_icon"';

String introMessage(String currentVersion) => '''
Expand Down
14 changes: 14 additions & 0 deletions lib/custom_exceptions.dart
Expand Up @@ -39,3 +39,17 @@ class NoDecoderForImageFormatException implements Exception {
return generateError(this, message);
}
}

/// A exception to throw when given [fileName] is not found
class FileNotFoundException implements Exception {
/// Creates a instance of [FileNotFoundException].
const FileNotFoundException(this.fileName);

/// Name of the file
final String fileName;

@override
String toString() {
return generateError(this, '$fileName file not found');
}
}

0 comments on commit a69a4e9

Please sign in to comment.