diff --git a/lib/configurations/configurations.json b/lib/configurations/configurations.json index d745b6e1..89102854 100644 --- a/lib/configurations/configurations.json +++ b/lib/configurations/configurations.json @@ -10,5 +10,6 @@ "desktop": 1280 }, "scaling": true, - "enablePrototyping": false + "enablePrototyping": false, + "componentIsolation": "none" } diff --git a/lib/controllers/interpret.dart b/lib/controllers/interpret.dart index 41574627..311270af 100644 --- a/lib/controllers/interpret.dart +++ b/lib/controllers/interpret.dart @@ -30,7 +30,7 @@ class Interpret { PBPrototypeLinkerService _pbPrototypeLinkerService; - final List aitHandlers = [ + List aitHandlers = [ StateManagementNodeInterpreter(), PBSymbolLinkerService(), // PBPluginControlService(), @@ -43,9 +43,13 @@ class Interpret { Future interpretAndOptimize( PBIntermediateTree tree, PBContext context, PBProject project, {List handlers, AITServiceBuilder aitServiceBuilder}) async { - handlers ??= aitHandlers; + if (handlers == null || handlers.isEmpty) { + handlers = aitHandlers; + } else { + handlers.addAll(aitHandlers); + } - aitServiceBuilder ??= AITServiceBuilder(aitHandlers); + aitServiceBuilder ??= AITServiceBuilder(handlers); var elementStorage = ElementStorage(); elementStorage.elementToTree[tree.rootNode.UUID] = tree.UUID; @@ -59,10 +63,12 @@ class Interpret { elementStorage.elementToTree[node.UUID] = tree.UUID; return Future.value(node); }, index: 0, id: 'Indexing ${tree.name}').addTransformation( - (PBContext context, PBIntermediateTree tree) { - tree - .whereType() - .forEach((node) => tree.remove(node, keepChildren: true)); + (PBContext context, PBIntermediateTree tree) async { + // + var baseGroupList = tree.whereType(); + + baseGroupList.forEach((group) => tree.remove(group, keepChildren: true)); + return Future.value(tree); }, index: 1, id: 'Removing the $BaseGroup from ${tree.name}'); diff --git a/lib/controllers/main_info.dart b/lib/controllers/main_info.dart index 8178bcad..62c179a9 100644 --- a/lib/controllers/main_info.dart +++ b/lib/controllers/main_info.dart @@ -57,7 +57,10 @@ class MainInfo { String get projectName => _projectName ?? configuration?.projectName; set projectName(String name) => _projectName = name; - /// API needed to do API callls + /// OAuth Token to call Figma API + String figmaOauthToken; + + /// API key needed to do API calls String figmaKey; /// Project ID on Figma diff --git a/lib/generation/flutter_project_builder/flutter_project_builder.dart b/lib/generation/flutter_project_builder/flutter_project_builder.dart index e09b66d2..733a062a 100644 --- a/lib/generation/flutter_project_builder/flutter_project_builder.dart +++ b/lib/generation/flutter_project_builder/flutter_project_builder.dart @@ -1,6 +1,7 @@ import 'dart:convert'; import 'dart:io'; import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/post_gen_task.dart'; import 'package:parabeac_core/generation/generators/writers/pb_flutter_writer.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -41,6 +42,9 @@ class FlutterProjectBuilder { bool _configured = false; + /// Tasks to be run after generation is complete. + List postGenTasks = []; + FlutterProjectBuilder( this.generationConfiguration, this.fileSystemAnalyzer, { @@ -65,7 +69,7 @@ class FlutterProjectBuilder { static Future createFlutterProject(String flutterProjectName, {String projectDir, bool createAssetsDir = true, - String assetsDir = 'assets/images/'}) async { + String assetsDir = 'lib/assets/images/'}) async { try { var result = await Process.run('flutter', ['create', flutterProjectName], workingDirectory: projectDir, runInShell: true); @@ -123,6 +127,11 @@ class FlutterProjectBuilder { ; } + /// Runs all the tasks in + void executePostGenTasks() { + postGenTasks.forEach((task) => task.execute()); + } + Future genAITree( PBIntermediateTree tree, PBContext context, bool isDryRun) async { if (!_configured) { diff --git a/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart new file mode 100644 index 00000000..9ef05645 --- /dev/null +++ b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart @@ -0,0 +1,17 @@ +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; + +/// Class that represents a Component Isolation Generator. +/// +/// This class sets up the Component Isolation Package (i.e. Widgetbook, Dashbook, etc.) +/// to create the necessary classes and generate the code at the end. +abstract class ComponentIsolationGenerator { + /// Method that generates the code for this generator. + String generateCode(ImportHelper importHelper); + + /// Path to the file to be written, relative to the `lib` directory. + String fileName; + + /// projectData used to add dependencies to the project. + PBGenerationProjectData projectData; +} diff --git a/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart new file mode 100644 index 00000000..67d5b989 --- /dev/null +++ b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart @@ -0,0 +1,35 @@ +/// Class that represents a generic Component Isolation Node. +/// +/// For instance, Widgetbook may have Categories, Folders, etc., +/// while Dashbook has Stories and Chapters. This node can represent +/// these in a generic way. +abstract class IsolationNode { + String name; + + List children; + + /// Generates a string representation of how the + /// [IsolationNode] should be printed. + String generate(); + + IsolationNode({this.children, this.name}) { + children ??= []; + } + + /// Adds a child to the [IsolationNode]. + void addChild(IsolationNode child) { + children.add(child); + } + + List getType() => + children.whereType().toList(); + + /// Returns [IsolationNode] with type [T] and name [name]. + /// + /// Returns null if no such node exists. + IsolationNode getNamed(String name) => + children.whereType().firstWhere( + (element) => element.name == name, + orElse: () => null, + ); +} diff --git a/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_post_gen_task.dart b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_post_gen_task.dart new file mode 100644 index 00000000..917fd058 --- /dev/null +++ b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_post_gen_task.dart @@ -0,0 +1,25 @@ +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/post_gen_task.dart'; +import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/write_symbol_command.dart'; +import 'package:parabeac_core/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart'; + +/// This class is responsible for coordinating the generation of the +/// component isolation code based on the given configuration. +class IsolationPostGenTask implements PostGenTask { + /// Specific instance of the configuration to execute + ComponentIsolationGenerator compIsoConfiguration; + + /// GenerationConfiguration to get strategy and imports + GenerationConfiguration generationConfiguration; + IsolationPostGenTask(this.compIsoConfiguration, this.generationConfiguration); + @override + void execute() { + var isolationCode = compIsoConfiguration.generateCode( + generationConfiguration.generationManager.importProcessor); + var fileName = compIsoConfiguration.fileName; + + /// TODO: WriteSymbolCommand was used as a workaround. We should generate a command that generically writes any file + generationConfiguration.fileStructureStrategy.commandCreated( + WriteSymbolCommand(null, fileName, isolationCode, symbolPath: 'lib/')); + } +} diff --git a/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_category.dart b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_category.dart new file mode 100644 index 00000000..8f2615c3 --- /dev/null +++ b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_category.dart @@ -0,0 +1,33 @@ +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_folder.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_widget.dart'; + +/// Class that represents a WidgetBook Category. +class WidgetBookCategory extends IsolationNode { + WidgetBookCategory({ + String name = 'Parabeac-Generated', + }) : super(name: name); + + @override + String generate() { + var folders = getType(); + var widgets = getType(); + + var folderGen = ''; + var widgetsGen = ''; + + if (folders != null && folders.isNotEmpty) { + folderGen = folders.map((f) => f.generate()).join('\n'); + } + if (widgets != null && widgets.isNotEmpty) { + widgetsGen = widgets.map((w) => w.generate()).join('\n'); + } + return ''' + WidgetbookCategory( + name: 'Parabeac-Generated', + ${folderGen.isNotEmpty ? 'folders: [\n$folderGen\n],\n' : ''} + ${widgetsGen.isNotEmpty ? 'widgets: [\n$widgetsGen\n],\n' : ''} + ) + '''; + } +} diff --git a/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_folder.dart b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_folder.dart new file mode 100644 index 00000000..3bc52d52 --- /dev/null +++ b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_folder.dart @@ -0,0 +1,21 @@ +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_widget.dart'; + +class WidgetBookFolder extends IsolationNode { + WidgetBookFolder(String name) : super(name: name); + + @override + String generate() { + var widgets = getType(); + var genWidgets = ''; + if (widgets != null && widgets.isNotEmpty) { + genWidgets = widgets.map((node) => node.generate()).join(',\n'); + } + return ''' + WidgetbookFolder( + name: '$name', + ${genWidgets.isNotEmpty ? 'widgets: [\n$genWidgets\n],\n' : ''} + ) + '''; + } +} diff --git a/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_use_case.dart b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_use_case.dart new file mode 100644 index 00000000..479edc30 --- /dev/null +++ b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_use_case.dart @@ -0,0 +1,16 @@ +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; + +class WidgetBookUseCase extends IsolationNode { + String builderCode; + WidgetBookUseCase(String name, this.builderCode) : super(name: name); + + @override + String generate() { + return ''' + WidgetbookUseCase( + name: '$name', + builder: (context) => Center(child: $builderCode), + ), + '''; + } +} diff --git a/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_widget.dart b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_widget.dart new file mode 100644 index 00000000..6b6237cf --- /dev/null +++ b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_widget.dart @@ -0,0 +1,22 @@ +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_node.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_use_case.dart'; + +/// Node that represents a Widgetbook component. +class WidgetBookWidget extends IsolationNode { + WidgetBookWidget(String name) : super(name: name); + + @override + String generate() { + var useCases = getType(); + var useCasesGen = ''; + if (useCases != null && useCases.isNotEmpty) { + useCasesGen = useCases.map((useCase) => useCase.generate()).join('\n'); + } + return ''' + WidgetbookWidget( + name: '$name', + ${useCasesGen.isNotEmpty ? 'useCases: [\n$useCasesGen\n],\n' : ''} + ) + '''; + } +} diff --git a/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/widgetbook_generator.dart b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/widgetbook_generator.dart new file mode 100644 index 00000000..2d042572 --- /dev/null +++ b/lib/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/widgetbook_generator.dart @@ -0,0 +1,69 @@ +import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/import_helper.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart'; +import 'package:parabeac_core/generation/generators/import_generator.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/component_isolation/widgetbook_service.dart'; + +class WidgetbookGenerator implements ComponentIsolationGenerator { + @override + String fileName = 'main_widgetbook.dart'; + + WidgetbookGenerator(this.projectData) { + projectData.addDependencies('widgetbook', '2.0.5-beta'); + } + + @override + PBGenerationProjectData projectData; + + @override + String generateCode(ImportHelper helper) { + var category = WidgetBookService.category; + var treeIds = WidgetBookService.treeIds; + var generatedCode = category.generate(); + + var imports = treeIds + .map( + (id) => helper + .getFormattedImports( + id, + importMapper: (import) => FlutterImport( + import, + MainInfo().projectName, + ), + ) + .join('\n'), + ) + .join(''); + return ''' + import 'package:widgetbook/widgetbook.dart'; + import 'package:flutter/material.dart'; + $imports + + void main() { + runApp(const MyApp()); + } + + class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context){ + return Widgetbook( + themes: [ + WidgetbookTheme(name: 'Light', data: ThemeData.light()), + ], + devices: const [ + Apple.iPhone11ProMax, + Samsung.s10, + ], + categories: [ + $generatedCode, + ], + appInfo: AppInfo(name: 'MyApp'), + ); + } + } + '''; + } +} diff --git a/lib/generation/flutter_project_builder/post_gen_tasks/post_gen_task.dart b/lib/generation/flutter_project_builder/post_gen_tasks/post_gen_task.dart new file mode 100644 index 00000000..2907985e --- /dev/null +++ b/lib/generation/flutter_project_builder/post_gen_tasks/post_gen_task.dart @@ -0,0 +1,5 @@ +/// Abstract class for Tasks that will run post-generation. +abstract class PostGenTask { + /// Executes the [PostGenTask]. + void execute(); +} diff --git a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart index a3ad3933..24e7723a 100644 --- a/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart +++ b/lib/generation/generators/value_objects/file_structure_strategy/commands/add_dependency_command.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/commands/file_structure_command.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy/pb_file_structure_strategy.dart'; @@ -6,7 +7,8 @@ class AddDependencyCommand extends FileStructureCommand { final _PUBSPEC_YAML_NAME = 'pubspec.yaml'; ///assets yaml decleration - final String _ASSET_DECLERATION = '\t\t- assets/images/'; + final String _ASSET_DECLERATION = + '\t\t- packages/${MainInfo().projectName}/assets/images/'; /// Name of the [package] String package; diff --git a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart index a26ee4fa..77942a6d 100644 --- a/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_bitmap_gen.dart @@ -40,8 +40,11 @@ class PBBitmapGenerator extends PBGenerator { ? 'assets/${source.referenceImage}' // Assuming PBDL will give us reference to image in the form of `image/.png` : ('assets/images/' + source.UUID + '.png'); - buffer.write( - '\'$imagePath\', ${_sizehelper.generate(source, generatorContext)} $boxFit)'); + buffer.write('\'$imagePath\', '); + // Point package to self (for component isolation support) + buffer.write('package: \'${MainInfo().projectName}\','); + buffer.write('${_sizehelper.generate(source, generatorContext)} $boxFit)'); + return buffer.toString(); } diff --git a/lib/generation/generators/visual-widgets/pb_shape_group_gen.dart b/lib/generation/generators/visual-widgets/pb_shape_group_gen.dart index d6261514..a3ad4f6e 100644 --- a/lib/generation/generators/visual-widgets/pb_shape_group_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_shape_group_gen.dart @@ -1,3 +1,4 @@ +import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/attribute-helper/pb_size_helper.dart'; import 'package:parabeac_core/generation/generators/pb_generator.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/inherited_shape_group.dart'; @@ -15,7 +16,7 @@ class PBShapeGroupGen extends PBGenerator { if (source is InheritedShapeGroup) { var buffer = StringBuffer(); buffer.write( - 'Image.asset(\'assets/images/${source.UUID}.png\', ${_sizehelper.generate(source)})'); + 'Image.asset(\'assets/images/${source.UUID}.png\', ${_sizehelper.generate(source)}), package: \'${MainInfo().projectName}\','); return buffer.toString(); } } diff --git a/lib/generation/generators/visual-widgets/pb_text_gen.dart b/lib/generation/generators/visual-widgets/pb_text_gen.dart index 1379ca7c..c97a657e 100644 --- a/lib/generation/generators/visual-widgets/pb_text_gen.dart +++ b/lib/generation/generators/visual-widgets/pb_text_gen.dart @@ -9,11 +9,12 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; class PBTextGen extends PBGenerator { PBTextGen() : super(); + static String cleanString(String text) => + text.replaceAll('\n', ' ')?.replaceAll('\'', '\\\'') ?? ''; @override String generate(PBIntermediateNode source, PBContext context) { if (source is InheritedText) { - var cleanText = - source.text?.replaceAll('\n', ' ')?.replaceAll('\'', '\\\'') ?? ''; + var cleanText = cleanString(source.text); context.project.genProjectData.addDependencies('auto_size_text', '3.0.0'); context.managerData diff --git a/lib/generation/generators/writers/pb_flutter_writer.dart b/lib/generation/generators/writers/pb_flutter_writer.dart index 7d952080..7cd10a1f 100644 --- a/lib/generation/generators/writers/pb_flutter_writer.dart +++ b/lib/generation/generators/writers/pb_flutter_writer.dart @@ -2,6 +2,8 @@ import 'dart:io'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/generators/import_generator.dart'; import 'package:parabeac_core/generation/generators/writers/pb_page_writer.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_image_reference_storage.dart'; +import 'package:yaml_modify/yaml_modify.dart'; ///Responsible for writing code into files in the desired folder structure class PBFlutterWriter implements PBPageWriter { @@ -11,7 +13,6 @@ class PBFlutterWriter implements PBPageWriter { factory PBFlutterWriter() => _instance; - ///[fileAbsPath] should be the absolute path of the file @override void write(String code, String fileAbsPath) { @@ -76,27 +77,60 @@ class MyApp extends StatelessWidget { } void submitDependencies( - String yamlAbsPath, Map dependencies) async { - var line = 0; - var readYaml = File(yamlAbsPath).readAsLinesSync(); - if (dependencies.isNotEmpty) { - line = readYaml.indexOf('dependencies:'); - if (line > 0) { - dependencies.forEach((packageName, version) { - if (!readYaml.contains(' $packageName: $version')) { - readYaml.insert(++line, ' $packageName: $version'); - } - }); - - dependencies.clear(); // Clear dependencies to prevent duplicates - } + String yamlAbsPath, Map dependencies) { + var yamlStr = File(yamlAbsPath).readAsStringSync(); + var modifiableyaml = getModifiableNode(loadYaml(yamlStr)) as Map; + + /// Add new dependencies to pubspec.yaml + if (dependencies.isNotEmpty && modifiableyaml.containsKey('dependencies')) { + var yamlDeps = modifiableyaml['dependencies'] as Map; + + /// Check if dependency already exists. + /// Add dependency if it does not exist already. + dependencies.forEach((name, version) { + if (!yamlDeps.containsKey(name)) { + yamlDeps[name] = version; + } + }); + + dependencies.clear(); } - line = readYaml.indexOf('flutter:'); - if (line > 0) { - if (!readYaml.contains(' assets:')) { - readYaml.insert(++line, ' assets:\n - assets/images/'); + + /// Add assets + if (modifiableyaml.containsKey('flutter')) { + /// Create `assets` entry if does not exist + if (!modifiableyaml['flutter'].containsKey('assets')) { + modifiableyaml['flutter']['assets'] = []; + } + + var yamlAssets = + (modifiableyaml['flutter']['assets'] as List).cast(); + + var assets = _getAssetFileNames(); + + /// Add dependency for each asset + for (var assetName in assets) { + if (!yamlAssets.any((str) => str.endsWith('/$assetName'))) { + yamlAssets.add( + 'packages/${MainInfo().projectName}/assets/images/$assetName'); + } } } - File(yamlAbsPath).writeAsStringSync(readYaml.join('\n')); + + /// Write the new yaml file + File(yamlAbsPath).writeAsStringSync(toYamlString(modifiableyaml)); + } + + /// Returns a [List] of all the `filenames` of `pngs` listed under `assets/images/` + List _getAssetFileNames() { + try { + // Return names inside image reference storage + return ImageReferenceStorage() + .names + .map((imageName) => '${imageName.replaceAll(':', '_')}.png') + .toList(); + } catch (e) { + return []; + } } } diff --git a/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart b/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart deleted file mode 100644 index 936fdfe6..00000000 --- a/lib/input/sketch/helper/sketch_constraint_to_pbdl.dart +++ /dev/null @@ -1,359 +0,0 @@ -// import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pbdl_constraints.dart'; - -// PBDLConstraints convertSketchConstraintToPBDLConstraint( -// int resizingConstraint) { -// var constraints = sketchConstraintBitFieldToPBDLMap[resizingConstraint]; -// if (constraints == null) { -// print( -// '[PBDL Conversion Error] We don\' support this `resizingConstraint` from Sketch.'); -// } -// return constraints; -// } - -// /// A map that references the Sketch Constraint Bitmap to PBDL Constraints. -// /// For reference: https://www.notion.so/parabeac/2ff2c018c44644d9bba6bc4567f249c2?v=5c9a4978c96b4ee1aab8b219e3a2c006 -// var sketchConstraintBitFieldToPBDLMap = { -// 63: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: false, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: false), -// 18: PBDLConstraints( -// pinLeft: true, -// pinRight: true, -// pinTop: true, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: false), -// 31: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: true, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: false), -// 27: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: true, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: false), -// 19: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: true, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: false), -// 22: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: true, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: false), -// 30: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: true, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: false), -// 26: PBDLConstraints( -// pinLeft: true, -// pinRight: true, -// pinTop: true, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: false), -// 23: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: true, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: false), -// 59: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: false, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: false), -// 51: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: false, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: false), -// 50: PBDLConstraints( -// pinLeft: true, -// pinRight: true, -// pinTop: false, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: false), -// 58: PBDLConstraints( -// pinLeft: true, -// pinRight: true, -// pinTop: false, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: false), -// 55: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: false, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: false), -// 54: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: false, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: false), -// 62: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: false, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: false), -// 61: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: false, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: true), -// 29: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: true, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: true), -// 25: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: true, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: true), -// 17: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: true, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: true), -// 57: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: false, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: true), -// 49: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: false, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: true), -// 53: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: false, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: true), -// 52: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: false, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: true), -// 20: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: true, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: true), -// 60: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: false, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: true), -// 28: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: true, -// pinBottom: false, -// fixedHeight: false, -// fixedWidth: true), -// 21: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: true, -// pinBottom: true, -// fixedHeight: false, -// fixedWidth: true), -// 47: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: false, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: false), -// 15: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: true, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: false), -// 11: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: true, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: false), -// 43: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: false, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: false), -// 35: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: false, -// pinBottom: true, -// fixedHeight: true, -// fixedWidth: false), -// 34: PBDLConstraints( -// pinLeft: true, -// pinRight: true, -// pinTop: false, -// pinBottom: true, -// fixedHeight: true, -// fixedWidth: false), -// 39: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: false, -// pinBottom: true, -// fixedHeight: true, -// fixedWidth: false), -// 38: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: false, -// pinBottom: true, -// fixedHeight: true, -// fixedWidth: false), -// 46: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: false, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: false), -// 14: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: true, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: false), -// 10: PBDLConstraints( -// pinLeft: true, -// pinRight: true, -// pinTop: true, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: false), -// 42: PBDLConstraints( -// pinLeft: true, -// pinRight: true, -// pinTop: false, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: false), -// 45: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: false, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: true), -// 13: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: true, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: true), -// 9: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: true, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: true), -// 41: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: false, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: true), -// 33: PBDLConstraints( -// pinLeft: true, -// pinRight: false, -// pinTop: false, -// pinBottom: true, -// fixedHeight: true, -// fixedWidth: true), -// 37: PBDLConstraints( -// pinLeft: false, -// pinRight: false, -// pinTop: false, -// pinBottom: true, -// fixedHeight: true, -// fixedWidth: true), -// 36: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: false, -// pinBottom: true, -// fixedHeight: true, -// fixedWidth: true), -// 44: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: false, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: true), -// 12: PBDLConstraints( -// pinLeft: false, -// pinRight: true, -// pinTop: true, -// pinBottom: false, -// fixedHeight: true, -// fixedWidth: true) -// }; diff --git a/lib/interpret_and_optimize/entities/inherited_bitmap.dart b/lib/interpret_and_optimize/entities/inherited_bitmap.dart index d5bec916..1f37eae1 100644 --- a/lib/interpret_and_optimize/entities/inherited_bitmap.dart +++ b/lib/interpret_and_optimize/entities/inherited_bitmap.dart @@ -44,9 +44,10 @@ class InheritedBitmap extends PBVisualIntermediateNode }) : super(UUID, frame, name, constraints: constraints) { generator = PBBitmapGenerator(); childrenStrategy = NoChildStrategy(); - - ImageReferenceStorage() - .addReference(UUID, '${MainInfo().outputPath}assets/images'); + if (name != null && name.isNotEmpty) { + ImageReferenceStorage() + .addReference(UUID, '${MainInfo().outputPath}assets/images'); + } } static PBIntermediateNode fromJson(Map json) => diff --git a/lib/interpret_and_optimize/entities/inherited_shape_group.dart b/lib/interpret_and_optimize/entities/inherited_shape_group.dart index dcc59982..d4f53063 100644 --- a/lib/interpret_and_optimize/entities/inherited_shape_group.dart +++ b/lib/interpret_and_optimize/entities/inherited_shape_group.dart @@ -48,9 +48,10 @@ class InheritedShapeGroup extends PBVisualIntermediateNode }) : super(UUID, frame, name, constraints: constraints) { generator = PBBitmapGenerator(); childrenStrategy = NoChildStrategy(); - - ImageReferenceStorage().addReferenceAndWrite( - UUID, p.join(MainInfo().outputPath, 'assets/images'), image); + if (image != null) { + ImageReferenceStorage().addReferenceAndWrite( + UUID, p.join(MainInfo().outputPath, 'assets/images'), image); + } } static PBIntermediateNode fromJson(Map json) { diff --git a/lib/interpret_and_optimize/helpers/component_isolation_configuration.dart b/lib/interpret_and_optimize/helpers/component_isolation_configuration.dart new file mode 100644 index 00000000..1f48b56c --- /dev/null +++ b/lib/interpret_and_optimize/helpers/component_isolation_configuration.dart @@ -0,0 +1,25 @@ +import 'package:parabeac_core/controllers/interpret.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/component_isolation_generator.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/widgetbook_generator.dart'; +import 'package:parabeac_core/generation/generators/util/pb_generation_project_data.dart'; +import 'package:parabeac_core/interpret_and_optimize/services/component_isolation/widgetbook_service.dart'; + +/// Class that bundles a ComponentIsolationGenerator and an AITHandler +/// to generate the component isolation package according to the type. +class ComponentIsolationConfiguration { + ComponentIsolationGenerator generator; + AITHandler service; + + ComponentIsolationConfiguration._internal(this.generator, this.service); + + factory ComponentIsolationConfiguration.getConfiguration( + String type, PBGenerationProjectData projectData) { + switch (type.toLowerCase()) { + case 'widgetbook': + return ComponentIsolationConfiguration._internal( + WidgetbookGenerator(projectData), WidgetBookService()); + default: + return null; + } + } +} diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.dart b/lib/interpret_and_optimize/helpers/pb_configuration.dart index 00180a39..aa1c8b5d 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.dart @@ -52,6 +52,9 @@ class PBConfiguration { @JsonKey(defaultValue: false) final bool enablePrototyping; + @JsonKey(defaultValue: 'None') + final String componentIsolation; + PBConfiguration( this.widgetStyle, this.widgetType, @@ -61,6 +64,7 @@ class PBConfiguration { this.breakpoints, this.scaling, this.enablePrototyping, + this.componentIsolation, ); /// Converting the [json] into a [PBConfiguration] object. diff --git a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart index a0954c97..2927f498 100644 --- a/lib/interpret_and_optimize/helpers/pb_configuration.g.dart +++ b/lib/interpret_and_optimize/helpers/pb_configuration.g.dart @@ -17,6 +17,7 @@ PBConfiguration _$PBConfigurationFromJson(Map json) { json['breakpoints'] as Map, json['scaling'] as bool ?? true, json['enablePrototyping'] as bool ?? false, + json['componentIsolation'] as String ?? 'None', ); } diff --git a/lib/interpret_and_optimize/helpers/pb_context.dart b/lib/interpret_and_optimize/helpers/pb_context.dart index 17d9f6f4..1dcadf2e 100644 --- a/lib/interpret_and_optimize/helpers/pb_context.dart +++ b/lib/interpret_and_optimize/helpers/pb_context.dart @@ -13,12 +13,11 @@ class PBContext { Rectangle3D _screenFrame; Rectangle3D get screenFrame => _screenFrame; - set screenFrame(Rectangle3D frame){ + set screenFrame(Rectangle3D frame) { canvasFrame ??= Rectangle3D.fromPoints(frame.topLeft, frame.bottomRight); _screenFrame = frame; } - /// These values represent the current "focus area" size as it travels down the /// tree. /// @@ -70,9 +69,7 @@ class PBContext { if (size == 0) { return size; } - return isHorizontal - ? size / screenFrame.width - : size / screenFrame.height; + return isHorizontal ? size / screenFrame.width : size / screenFrame.height; } PBContext clone() { @@ -86,6 +83,30 @@ class PBContext { context.screenFrame = _screenFrame; return context; } + + PBContext copyWith({ + PBConfiguration configuration, + PBIntermediateTree tree, + PBIntermediateConstraints contextConstraints, + PBSharedMasterNode masterNode, + PBProject project, + Rectangle3D canvasFrame, + PBGenerationManager generationManager, + SizingValueContext sizingContext, + Rectangle3D screenFrame, + }) { + return PBContext( + configuration ?? this.configuration, + tree: tree ?? this.tree, + contextConstraints: contextConstraints ?? this.contextConstraints, + masterNode: masterNode ?? this.masterNode, + project: project ?? this.project, + canvasFrame: canvasFrame ?? this.canvasFrame, + generationManager: generationManager ?? this.generationManager, + ) + ..sizingContext = sizingContext ?? this.sizingContext + ..screenFrame = screenFrame ?? this.screenFrame; + } } enum SizingValueContext { diff --git a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart index b412dbc7..d41752cc 100644 --- a/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart +++ b/lib/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart @@ -125,6 +125,25 @@ class PBIntermediateTree extends DirectedGraph { _elementStorage = ElementStorage(); } + /// Finds a [PBIntermediateNode] that is a child of `parent` of `type` in the [PBIntermediateTree], containing `name`. + /// + /// Returns null if not found. + PBIntermediateNode findChild(PBIntermediateNode parent, String name, Type type) { + /// Check if the node is a match + if (parent.name.contains(name) && parent.runtimeType == type) { + return parent; + } + + /// Check if node's children are a match + for (var child in childrenOf(parent)) { + var result = findChild(child, name, type); + if (result != null) { + return result; + } + } + return null; + } + /// These are observers of [Vertex] that will be added into [this] void addChildrenObeserver(String UUID, ChildrenModEventHandler oberver) { var mods = _childrenModObservers[UUID] ?? []; diff --git a/lib/interpret_and_optimize/services/component_isolation/widgetbook_service.dart b/lib/interpret_and_optimize/services/component_isolation/widgetbook_service.dart new file mode 100644 index 00000000..e95baa73 --- /dev/null +++ b/lib/interpret_and_optimize/services/component_isolation/widgetbook_service.dart @@ -0,0 +1,82 @@ +import 'package:parabeac_core/controllers/interpret.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_category.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_folder.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_use_case.dart'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/widgetbook/entities/widgetbook_widget.dart'; +import 'package:parabeac_core/generation/generators/attribute-helper/pb_size_helper.dart'; +import 'package:parabeac_core/generation/generators/symbols/pb_instancesym_gen.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_instance.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; +import 'package:recase/recase.dart'; + +class WidgetBookService extends AITHandler { + /// Map that holds the name of the folder as its key, and the folder as its value. + + // FIXME: The reason these are static is because otherwise we'd need a service that can + // gather the folders, widgets, and categories to pass it to the ComponentIsolationService. + // The treeIds need to be gathered to generate the imports later on as well. + static Map _widgetBookFolders; + static Map _widgetBookWidgets; + static WidgetBookCategory category = WidgetBookCategory(); + static final treeIds = []; + + WidgetBookService() { + _widgetBookFolders = {}; + _widgetBookWidgets = {}; + } + + @override + Future handleTree( + PBContext context, PBIntermediateTree tree) async { + /// Only process [PBSharedMasterNode]s. + if (tree.rootNode is PBSharedMasterNode) { + treeIds.add(tree.UUID); + + /// Create a new folder if it doesn't exist. + if (!_widgetBookFolders.containsKey(tree.name)) { + _widgetBookFolders[tree.name] = WidgetBookFolder(tree.name); + category.addChild(_widgetBookFolders[tree.name]); + } + + var component = tree.rootNode as PBSharedMasterNode; + var rootName = component.componentSetName ?? tree.rootNode.name; + + /// Create new Widget for this variation if it doesn't exist already + if (!_widgetBookWidgets.containsKey(rootName)) { + _widgetBookWidgets[rootName] = WidgetBookWidget(rootName); + _widgetBookFolders[tree.name].addChild(_widgetBookWidgets[rootName]); + } + + /// Create a fake instance in order to generate the Use Case. + // FIXME: Generating the code should happen somewhere in generate, not here. + var dummyInstance = PBSharedInstanceIntermediateNode( + null, + tree.rootNode.frame.copyWith(), + SYMBOL_ID: component.SYMBOL_ID, + name: rootName, + sharedNodeSetID: component.sharedNodeSetID, + ); + var sizeHelper = PBSizeHelper(); + + var generatedCode = ''' + SizedBox( + ${sizeHelper.generate(dummyInstance, context.copyWith(sizingContext: SizingValueContext.PointValue))} + child: ${(dummyInstance.generator as PBSymbolInstanceGenerator).generate( + dummyInstance, + context.copyWith(), + )}, + ), + '''; + + /// Create a use case for the current component and add it to the folder. + var useCase = WidgetBookUseCase( + (tree.rootNode as PBSharedMasterNode).name.pascalCase, + generatedCode, + ); + _widgetBookWidgets[rootName].addChild(useCase); + } + return tree; + } +} diff --git a/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart b/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart index 64d97b35..e5a70fba 100644 --- a/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart +++ b/lib/interpret_and_optimize/services/design_to_pbdl/figma_to_pbdl_service.dart @@ -11,8 +11,11 @@ class FigmaToPBDLService implements DesignToPBDLService { Future callPBDL(MainInfo info) { return PBDL.fromFigma( info.figmaProjectID, - info.figmaKey, - outputPath: p.join(info.genProjectPath, 'assets'), + key: info.figmaKey, + oauthKey: info.figmaOauthToken, + outputPath: p.join(info.genProjectPath, 'lib', 'assets'), + // Generating all assets inside lib folder for package isolation + pngPath: p.join(info.genProjectPath, 'lib', 'assets', 'images'), exportPbdlJson: info.exportPBDL, projectName: info.projectName, ); diff --git a/lib/main.dart b/lib/main.dart index c244f0f5..35f2136d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,11 +1,13 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'package:parabeac_core/generation/flutter_project_builder/post_gen_tasks/comp_isolation/isolation_post_gen_task.dart'; import 'package:parabeac_core/generation/generators/util/pb_generation_view_data.dart'; import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/generation/flutter_project_builder/file_system_analyzer.dart'; import 'package:parabeac_core/generation/flutter_project_builder/flutter_project_builder.dart'; +import 'package:parabeac_core/interpret_and_optimize/helpers/component_isolation_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_configuration.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_context.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_intermediate_node_tree.dart'; @@ -55,6 +57,7 @@ final parser = ArgParser() help: 'Takes in a Parabeac Design Logic (PBDL) JSON file and exports it to a project', ) + ..addOption('oauth', help: 'Figma OAuth Token') ..addFlag('help', help: 'Displays this help information.', abbr: 'h', negatable: false) ..addFlag('export-pbdl', @@ -113,6 +116,7 @@ ${parser.usage} } collectArguments(argResults); + var processInfo = MainInfo(); if (processInfo.designType == DesignType.UNKNOWN) { throw UnsupportedError('We have yet to support this DesignType! '); @@ -160,12 +164,22 @@ ${parser.usage} pbProject.forest.addAll(tempForest); - /// - var fpb = FlutterProjectBuilder( MainInfo().configuration.generationConfiguration, fileSystemAnalyzer, project: pbProject); + await fpb.preGenTasks(); + + /// Get ComponentIsolationService (if any), and add it to the list of services + var isolationConfiguration = ComponentIsolationConfiguration.getConfiguration( + MainInfo().configuration.componentIsolation, + pbProject.genProjectData, + ); + if (isolationConfiguration != null) { + interpretService.aitHandlers.add(isolationConfiguration.service); + fpb.postGenTasks.add(IsolationPostGenTask( + isolationConfiguration.generator, fpb.generationConfiguration)); + } await indexFileFuture; var trees = []; @@ -201,6 +215,8 @@ ${parser.usage} await fpb.genAITree(tree, tree.context, false); } + fpb.executePostGenTasks(); + exitCode = 0; } @@ -265,6 +281,7 @@ void collectArguments(ArgResults arguments) { /// Detect platform info.platform = Platform.operatingSystem; + info.figmaOauthToken = arguments['oauth']; info.figmaKey = arguments['figKey']; info.figmaProjectID = arguments['fig']; @@ -285,7 +302,7 @@ void collectArguments(ArgResults arguments) { /// In the future when we are generating certain dart files only. /// At the moment we are only generating in the flutter project. - info.pngPath = p.join(info.genProjectPath, 'assets/images'); + info.pngPath = p.join(info.genProjectPath, 'lib/assets/images'); } /// Determine the [MainInfo.designType] from the [arguments] @@ -296,7 +313,8 @@ void collectArguments(ArgResults arguments) { /// is [DesignType.PBDL].Finally, if none of the [DesignType] applies, its going to default /// to [DesignType.UNKNOWN]. DesignType determineDesignTypeFromArgs(ArgResults arguments) { - if (arguments['figKey'] != null && arguments['fig'] != null) { + if ((arguments['figKey'] != null || arguments['oauth'] != null) && + arguments['fig'] != null) { return DesignType.FIGMA; } else if (arguments['path'] != null) { return DesignType.SKETCH; @@ -383,7 +401,7 @@ void addToAmplitude() async { /// types of intake to parabeac-core bool hasTooManyArgs(ArgResults args) { var hasSketch = args['path'] != null; - var hasFigma = args['figKey'] != null || args['fig'] != null; + var hasFigma = args['figKey'] != null || args['fig'] != null || args['oauth']; var hasPbdl = args['pbdl-in'] != null; var hasAll = hasSketch && hasFigma && hasPbdl; @@ -395,7 +413,8 @@ bool hasTooManyArgs(ArgResults args) { /// to parabeac-core bool hasTooFewArgs(ArgResults args) { var hasSketch = args['path'] != null; - var hasFigma = args['figKey'] != null && args['fig'] != null; + var hasFigma = + (args['figKey'] != null || args['oauth'] != null) && args['fig'] != null; var hasPbdl = args['pbdl-in'] != null; return !(hasSketch || hasFigma || hasPbdl); diff --git a/parabeac.dart b/parabeac.dart index 0c9043a8..d35d55c9 100644 --- a/parabeac.dart +++ b/parabeac.dart @@ -35,6 +35,7 @@ main(List args) async { help: 'Takes in a Parabeac Design Logic (PBDL) JSON file and exports it to a project. The user should specify the absolute path of the location of the PBDL JSON file following this option. Example: `dart parabeac.dart --pbdl-in /path/to/pbdl.json -o /path/to/output/dir/`', ) + ..addOption('oauth', help: 'Figma OAuth Token') ..addFlag('export-pbdl', help: 'This flag outputs Parabeac Design Logic (PBDL) in JSON format. This flag is to be used along with Figma or Sketch conversion options.') diff --git a/pbdl b/pbdl index 4d360857..39cb9497 160000 --- a/pbdl +++ b/pbdl @@ -1 +1 @@ -Subproject commit 4d360857d1052c5ca87f1d033e55242e947aa6f1 +Subproject commit 39cb949751312d0e34a4a25c6b57949eef676ee1 diff --git a/pubspec.yaml b/pubspec.yaml index 42b0be5f..de9000ac 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: parabeac_core description: A starting point for Dart libraries or applications. -version: 2.3.0 +version: 2.4.0 # homepage: https://www.example.com environment: @@ -26,6 +26,7 @@ dependencies: path: ./pbdl directed_graph: ^0.2.3 sentry: ^6.2.2 + yaml_modify: ^1.0.1 dev_dependencies: pedantic: ^1.8.0