Skip to content

Commit

Permalink
Refactored the AssetGenImage code to be another Intergration, so it l…
Browse files Browse the repository at this point in the history
…ooks more similar to svg/lottie/etc.

This simplifies the assets_generator, and no longer forces AssetGenImage to be output even when there are no images.
  • Loading branch information
bramp committed Nov 13, 2023
1 parent ba28410 commit 2f1d80e
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 589 deletions.
109 changes: 4 additions & 105 deletions packages/core/lib/generators/assets_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:dart_style/dart_style.dart';
import 'package:dartx/dartx.dart';
import 'package:flutter_gen_core/generators/generator_helper.dart';
import 'package:flutter_gen_core/generators/integrations/flare_integration.dart';
import 'package:flutter_gen_core/generators/integrations/image_integration.dart';
import 'package:flutter_gen_core/generators/integrations/integration.dart';
import 'package:flutter_gen_core/generators/integrations/lottie_integration.dart';
import 'package:flutter_gen_core/generators/integrations/rive_integration.dart';
Expand Down Expand Up @@ -60,6 +61,7 @@ String generateAssets(
final classesBuffer = StringBuffer();

final integrations = <Integration>[
ImageIntegration(config.packageParameterLiteral),
if (config.flutterGen.integrations.flutterSvg)
SvgIntegration(config.packageParameterLiteral),
if (config.flutterGen.integrations.flareFlutter)
Expand Down Expand Up @@ -162,11 +164,7 @@ String generateAssets(
throw 'The value of "flutter_gen/assets/style." is incorrect.';
}

classesBuffer.writeln(_assetGenImageClassDefinition(
config.packageParameterLiteral,
));

final imports = <String>{'package:flutter/widgets.dart'};
final imports = <String>{};
integrations
.where((integration) => integration.isEnabled)
.forEach((integration) {
Expand Down Expand Up @@ -254,17 +252,7 @@ _Statement? _createAssetTypeStatement(
String name,
) {
final childAssetAbsolutePath = join(config.rootPath, assetType.path);
if (assetType.isSupportedImage) {
return _Statement(
type: 'AssetGenImage',
filePath: assetType.path,
name: name,
value: 'AssetGenImage(\'${posixStyle(assetType.path)}\')',
isConstConstructor: true,
isDirectory: false,
needDartDoc: true,
);
} else if (FileSystemEntity.isDirectorySync(childAssetAbsolutePath)) {
if (FileSystemEntity.isDirectorySync(childAssetAbsolutePath)) {
final childClassName = '\$${assetType.path.camelCase().capitalize()}Gen';
return _Statement(
type: childClassName,
Expand Down Expand Up @@ -535,95 +523,6 @@ class $className {
''';
}

String _assetGenImageClassDefinition(String packageName) {
final bool isPackage = packageName.isNotEmpty;
final packageParameter = isPackage ? ' = package' : '';

final keyName = packageName.isEmpty
? '_assetName'
: "'packages/$packageName/\$_assetName'";

return '''
class AssetGenImage {
const AssetGenImage(this._assetName);
final String _assetName;
${isPackage ? "\n static const String package = '$packageName';" : ''}
Image image({
Key? key,
AssetBundle? bundle,
ImageFrameBuilder? frameBuilder,
ImageErrorWidgetBuilder? errorBuilder,
String? semanticLabel,
bool excludeFromSemantics = false,
double? scale,
double? width,
double? height,
Color? color,
Animation<double>? opacity,
BlendMode? colorBlendMode,
BoxFit? fit,
AlignmentGeometry alignment = Alignment.center,
ImageRepeat repeat = ImageRepeat.noRepeat,
Rect? centerSlice,
bool matchTextDirection = false,
bool gaplessPlayback = false,
bool isAntiAlias = false,
${isPackage ? deprecationMessagePackage : ''}
String? package$packageParameter,
FilterQuality filterQuality = FilterQuality.low,
int? cacheWidth,
int? cacheHeight,
}) {
return Image.asset(
_assetName,
key: key,
bundle: bundle,
frameBuilder: frameBuilder,
errorBuilder: errorBuilder,
semanticLabel: semanticLabel,
excludeFromSemantics: excludeFromSemantics,
scale: scale,
width: width,
height: height,
color: color,
opacity: opacity,
colorBlendMode: colorBlendMode,
fit: fit,
alignment: alignment,
repeat: repeat,
centerSlice: centerSlice,
matchTextDirection: matchTextDirection,
gaplessPlayback: gaplessPlayback,
isAntiAlias: isAntiAlias,
package: package,
filterQuality: filterQuality,
cacheWidth: cacheWidth,
cacheHeight: cacheHeight,
);
}
ImageProvider provider({
AssetBundle? bundle,
${isPackage ? deprecationMessagePackage : ''}
String? package$packageParameter,
}) {
return AssetImage(
_assetName,
bundle: bundle,
package: package,
);
}
String get path => _assetName;
String get keyName => $keyName;
}
''';
}

class _Statement {
const _Statement({
required this.type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import 'package:flutter_gen_core/generators/integrations/integration.dart';
import 'package:flutter_gen_core/settings/asset_type.dart';

class FlareIntegration extends Integration {
FlareIntegration(String packageParameterLiteral)
: super(packageParameterLiteral);
FlareIntegration(String packageName) : super(packageName);

String? get packageExpression =>
isPackage ? 'packages/$packageParameterLiteral/' : null;
String? get packageExpression => isPackage ? 'packages/$packageName/' : null;

@override
List<String> get requiredImports => [
'package:flutter/widgets.dart',
'package:flare_flutter/flare_actor.dart',
'package:flare_flutter/flare_controller.dart',
];
Expand All @@ -21,7 +20,7 @@ class FlareIntegration extends Integration {
const FlareGenImage(this._assetName);
final String _assetName;
${isPackage ? "\n static const String package = '$packageParameterLiteral';" : ''}
${isPackage ? "\n static const String package = '$packageName';" : ''}
FlareActor flare({
String? boundsNode,
Expand Down
124 changes: 124 additions & 0 deletions packages/core/lib/generators/integrations/image_integration.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import 'package:flutter_gen_core/generators/integrations/integration.dart';
import 'package:flutter_gen_core/settings/asset_type.dart';

/// The main image integration, supporting all image asset types. See
/// [isSupport] for the exact supported mime types.
///
/// This integration is by enabled by default.
class ImageIntegration extends Integration {
ImageIntegration(String packageName) : super(packageName);

String get packageParameter => isPackage ? ' = package' : '';

String get keyName =>
isPackage ? '_assetName' : "'packages/$packageName/\$_assetName'";

@override
List<String> get requiredImports => ['package:flutter/widgets.dart'];

@override
String get classOutput => _classDefinition;

String get _classDefinition => '''class AssetGenImage {
const AssetGenImage(this._assetName);
final String _assetName;
${isPackage ? "\n static const String package = '$packageName';" : ''}
Image image({
Key? key,
AssetBundle? bundle,
ImageFrameBuilder? frameBuilder,
ImageErrorWidgetBuilder? errorBuilder,
String? semanticLabel,
bool excludeFromSemantics = false,
double? scale,
double? width,
double? height,
Color? color,
Animation<double>? opacity,
BlendMode? colorBlendMode,
BoxFit? fit,
AlignmentGeometry alignment = Alignment.center,
ImageRepeat repeat = ImageRepeat.noRepeat,
Rect? centerSlice,
bool matchTextDirection = false,
bool gaplessPlayback = false,
bool isAntiAlias = false,
${isPackage ? deprecationMessagePackage : ''}
String? package$packageParameter,
FilterQuality filterQuality = FilterQuality.low,
int? cacheWidth,
int? cacheHeight,
}) {
return Image.asset(
_assetName,
key: key,
bundle: bundle,
frameBuilder: frameBuilder,
errorBuilder: errorBuilder,
semanticLabel: semanticLabel,
excludeFromSemantics: excludeFromSemantics,
scale: scale,
width: width,
height: height,
color: color,
opacity: opacity,
colorBlendMode: colorBlendMode,
fit: fit,
alignment: alignment,
repeat: repeat,
centerSlice: centerSlice,
matchTextDirection: matchTextDirection,
gaplessPlayback: gaplessPlayback,
isAntiAlias: isAntiAlias,
package: package,
filterQuality: filterQuality,
cacheWidth: cacheWidth,
cacheHeight: cacheHeight,
);
}
ImageProvider provider({
AssetBundle? bundle,
${isPackage ? deprecationMessagePackage : ''}
String? package$packageParameter,
}) {
return AssetImage(
_assetName,
bundle: bundle,
package: package,
);
}
String get path => _assetName;
String get keyName => $keyName;
}
''';

@override
String get className => 'AssetGenImage';

@override
String classInstantiate(String path) => 'AssetGenImage(\'$path\')';

@override
bool isSupport(AssetType type) {
/// https://api.flutter.dev/flutter/widgets/Image-class.html
switch (type.mime) {
case 'image/jpeg':
case 'image/png':
case 'image/gif':
case 'image/bmp':
case 'image/vnd.wap.wbmp':
case 'image/webp':
return true;
default:
return false;
}
}

@override
bool get isConstConstructor => true;
}
9 changes: 6 additions & 3 deletions packages/core/lib/generators/integrations/integration.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import 'package:flutter_gen_core/settings/asset_type.dart';

/// A base class for all integrations. An integration is a class that
/// generates code for a specific asset type.
abstract class Integration {
Integration(this.packageParameterLiteral);
Integration(this.packageName);

final String packageParameterLiteral;
late final bool isPackage = packageParameterLiteral.isNotEmpty;
/// The package name for this asset. If empty, the asset is not in a package.
final String packageName;
late final bool isPackage = packageName.isNotEmpty;

bool isEnabled = false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import 'package:path/path.dart' as p;
import 'package:pub_semver/pub_semver.dart';

class LottieIntegration extends Integration {
LottieIntegration(String packageParameterLiteral)
: super(packageParameterLiteral);
LottieIntegration(String packageName) : super(packageName);

// These are required keys for this integration.
static const lottieKeys = [
Expand All @@ -25,6 +24,7 @@ class LottieIntegration extends Integration {

@override
List<String> get requiredImports => [
'package:flutter/widgets.dart',
'package:lottie/lottie.dart',
];

Expand All @@ -35,7 +35,7 @@ class LottieIntegration extends Integration {
const LottieGenImage(this._assetName);
final String _assetName;
${isPackage ? "\n static const String package = '$packageParameterLiteral';" : ''}
${isPackage ? "\n static const String package = '$packageName';" : ''}
LottieBuilder lottie({
Animation<double>? controller,
Expand Down Expand Up @@ -89,7 +89,7 @@ ${isPackage ? "\n static const String package = '$packageParameterLiteral';" :
String get path => _assetName;
String get keyName => ${isPackage ? '\'packages/$packageParameterLiteral/\$_assetName\'' : '_assetName'};
String get keyName => ${isPackage ? '\'packages/$packageName/\$_assetName\'' : '_assetName'};
}''';

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import 'package:flutter_gen_core/generators/integrations/integration.dart';
import 'package:flutter_gen_core/settings/asset_type.dart';

class RiveIntegration extends Integration {
RiveIntegration(String packageParameterLiteral)
: super(packageParameterLiteral);
RiveIntegration(String packageName) : super(packageName);

String? get packageExpression =>
isPackage ? 'packages/$packageParameterLiteral/' : null;
String? get packageExpression => isPackage ? 'packages/$packageName/' : null;

@override
List<String> get requiredImports => [
'package:flutter/widgets.dart',
'package:rive/rive.dart',
];

Expand All @@ -20,7 +19,7 @@ class RiveIntegration extends Integration {
const RiveGenImage(this._assetName);
final String _assetName;
${isPackage ? "\n static const String package = '$packageParameterLiteral';" : ''}
${isPackage ? "\n static const String package = '$packageName';" : ''}
RiveAnimation rive({
String? artboard,
Expand Down
Loading

0 comments on commit 2f1d80e

Please sign in to comment.