From 7f99776429a8b02cac0fd5b853c45614f4c0dcf5 Mon Sep 17 00:00:00 2001 From: Ivan Huerta Date: Mon, 1 Feb 2021 16:32:05 -0700 Subject: [PATCH 01/16] Updated README for State Management (#238) --- README.md | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c05a2972..1c72a315 100644 --- a/README.md +++ b/README.md @@ -99,10 +99,27 @@ Since Figma operates from a cloud native approach we use the Figma File ID and a 4. Create a new Personal Access Token with the name Parabeac, you should then be prompted with your new API Key. Make sure to copy this as you wont be able to access it again after you click confirm. (It should look something like this: ```64522-a0e5509a-d5ce-47a8-880b-c295f9cb27ed``` ## Using State Management Configuration -Coming Soon... See [here](https://dev.to/parabeac/bloc-provider-riverpod-support-parabeac-core-v1-3-29pj)! +![State Management](https://kindling-sketch.s3.amazonaws.com/PB_to_Flutter_with_State_management.png) -## Metrics -Parabeac-core keeps track of how many times it is run. Although we do not collect any personal information, you can turn off metrics at any time by creating the environment variable `PB_METRICS = "false"`. +Parabeac-Core is able to export to different state management systems such as BLoC & Provider. Every developer team creates their Flutter apps differently, we added this support to help map the conversion in a more thoughtful & custom way. See [here for the release post](https://dev.to/parabeac/bloc-provider-riverpod-support-parabeac-core-v1-3-29pj) for more details! + +To set the state management configuration, head over to edit `/Parabeac-Core/lib/configurations/configurations.json`. In here you'll see code like the following + +``` bash + { + "default": { + "widgetStyle": "Material", + "widgetType": "Stateless", + "widgetSpacing": "Expanded", + "layoutPrecedence" : ["column", "row", "stack"] + }, + "state-management" : "None" +} +``` + +Here you can replace the `state-management` property to `bloc` or `provider`. Soon you can also set `riverpod`. + +You can learn how to easily create your own state management configuration in the [wiki](https://github.com/Parabeac/Parabeac-Core/wiki/How-to-Create-a-State-Management-Configuration), let us know if you're thinking about doing this and if you need any help! # Running the exported code ### Requirements From bf9babd3e892c7ee78b87bc0b25525c960eade00 Mon Sep 17 00:00:00 2001 From: Eddie Date: Mon, 1 Feb 2021 19:40:13 -0700 Subject: [PATCH 02/16] Update README.md --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index dcca1598..6938c74d 100644 --- a/README.md +++ b/README.md @@ -98,11 +98,10 @@ Since Figma operates from a cloud native approach we use the Figma File ID and a 3. Scroll Down to the "Create a new Personal Access Token" 4. Create a new Personal Access Token with the name Parabeac, you should then be prompted with your new API Key. Make sure to copy this as you wont be able to access it again after you click confirm. (It should look something like this: ```64522-a0e5509a-d5ce-47a8-880b-c295f9cb27ed``` -<<<<<<< HEAD -======= + ## Metrics Parabeac-core keeps track of how many times it is run. Although we do not collect any personal information, you can turn off metrics at any time by creating the environment variable `PB_METRICS = "false"`. ->>>>>>> dev + ## Using State Management Configuration ![State Management](https://kindling-sketch.s3.amazonaws.com/PB_to_Flutter_with_State_management.png) @@ -123,11 +122,8 @@ To set the state management configuration, head over to edit `/Parabeac-Core/lib ``` Here you can replace the `state-management` property to `bloc` or `provider`. Soon you can also set `riverpod`. -<<<<<<< HEAD You can learn how to easily create your own state management configuration in the [wiki](https://github.com/Parabeac/Parabeac-Core/wiki/How-to-Create-a-State-Management-Configuration), let us know if you're thinking about doing this and if you need any help! -======= ->>>>>>> dev You can learn how to easily create your own state management configuration in the [wiki](https://github.com/Parabeac/Parabeac-Core/wiki/How-to-Create-a-State-Management-Configuration), let us know if you're thinking about doing this and if you need any help! # Running the exported code From 098346bd34f3dcfcc7d75df87cc51d7505cbc8f9 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 8 Feb 2021 23:09:49 -0500 Subject: [PATCH 03/16] Moved `lib/ApiCaller` to `lib/input/figma/helper` --- lib/{APICaller => input/figma/helper}/api_call_service.dart | 0 lib/{APICaller => input/figma/helper}/api_exceptions.dart | 0 lib/input/figma/helper/figma_asset_processor.dart | 2 +- lib/main.dart | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename lib/{APICaller => input/figma/helper}/api_call_service.dart (100%) rename lib/{APICaller => input/figma/helper}/api_exceptions.dart (100%) diff --git a/lib/APICaller/api_call_service.dart b/lib/input/figma/helper/api_call_service.dart similarity index 100% rename from lib/APICaller/api_call_service.dart rename to lib/input/figma/helper/api_call_service.dart diff --git a/lib/APICaller/api_exceptions.dart b/lib/input/figma/helper/api_exceptions.dart similarity index 100% rename from lib/APICaller/api_exceptions.dart rename to lib/input/figma/helper/api_exceptions.dart diff --git a/lib/input/figma/helper/figma_asset_processor.dart b/lib/input/figma/helper/figma_asset_processor.dart index 12e9a32a..01415955 100644 --- a/lib/input/figma/helper/figma_asset_processor.dart +++ b/lib/input/figma/helper/figma_asset_processor.dart @@ -1,8 +1,8 @@ import 'dart:io'; import 'package:http/http.dart' as http; -import 'package:parabeac_core/APICaller/api_call_service.dart'; import 'package:parabeac_core/controllers/main_info.dart'; +import 'package:parabeac_core/input/figma/helper/api_call_service.dart'; import 'package:parabeac_core/input/helper/asset_processing_service.dart'; import 'package:quick_log/quick_log.dart'; diff --git a/lib/main.dart b/lib/main.dart index e458c31b..b209838b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,10 +1,10 @@ import 'dart:convert'; import 'dart:io'; -import 'package:parabeac_core/APICaller/api_call_service.dart'; import 'package:parabeac_core/controllers/design_controller.dart'; import 'package:parabeac_core/controllers/figma_controller.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/controllers/sketch_controller.dart'; +import 'package:parabeac_core/input/figma/helper/api_call_service.dart'; import 'package:parabeac_core/input/figma/helper/figma_asset_processor.dart'; import 'package:parabeac_core/input/helper/azure_asset_service.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_asset_processor.dart'; From 2dbe5410270d08d38b2dd6cfdc82d73832c6ae5f Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 8 Feb 2021 23:19:01 -0500 Subject: [PATCH 04/16] Fixed import paths in tests --- test/lib/input_services/figma_to_map_test.dart | 2 +- test/lib/input_services/input_to_pbdl_test.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/lib/input_services/figma_to_map_test.dart b/test/lib/input_services/figma_to_map_test.dart index 41f9eb21..d9cde83b 100644 --- a/test/lib/input_services/figma_to_map_test.dart +++ b/test/lib/input_services/figma_to_map_test.dart @@ -1,5 +1,5 @@ import 'dart:io'; -import 'package:parabeac_core/APICaller/api_call_service.dart'; +import 'package:parabeac_core/input/figma/helper/api_call_service.dart'; import 'package:test/test.dart'; void main() async { diff --git a/test/lib/input_services/input_to_pbdl_test.dart b/test/lib/input_services/input_to_pbdl_test.dart index 55a4057b..eb82a62b 100644 --- a/test/lib/input_services/input_to_pbdl_test.dart +++ b/test/lib/input_services/input_to_pbdl_test.dart @@ -1,8 +1,8 @@ import 'dart:io'; -import 'package:parabeac_core/APICaller/api_call_service.dart'; import 'package:parabeac_core/controllers/figma_controller.dart'; import 'package:parabeac_core/controllers/main_info.dart'; import 'package:parabeac_core/controllers/sketch_controller.dart'; +import 'package:parabeac_core/input/figma/helper/api_call_service.dart'; import 'package:parabeac_core/input/figma/helper/figma_page.dart'; import 'package:parabeac_core/input/figma/helper/figma_project.dart'; import 'package:parabeac_core/input/sketch/helper/sketch_page.dart'; From 8e0734afcd69a6a1cbd00738b5f241c8a4f62196 Mon Sep 17 00:00:00 2001 From: ivanhuerta20 Date: Sat, 13 Feb 2021 17:44:07 -0700 Subject: [PATCH 05/16] Updated README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6938c74d..5ffbcd24 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ Parabeac-Core is an open-source repository that converts design files into Flutt Community · Dev.to + · + Debugging # What is Parabeac-Core? From bfbbb94dd3ba09218d2ad3d7ec6d8a96aff2b3a8 Mon Sep 17 00:00:00 2001 From: Ian Hudson Date: Mon, 15 Feb 2021 17:13:51 -0700 Subject: [PATCH 06/16] Fixed Broken Link in Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ffbcd24..f704396a 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Parabeac-Core is an open-source repository that converts design files into Flutt · Dev.to · - Debugging + Debugging # What is Parabeac-Core? From 0c793a6e0611383931ed24cd5b7f989e78214a4a Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 16 Feb 2021 22:18:40 -0500 Subject: [PATCH 07/16] Added middleware utils to prevent code repetition between provider and riverpod --- .../utils/middleware_utils.dart | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 lib/generation/generators/middleware/state_management/utils/middleware_utils.dart diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart new file mode 100644 index 00000000..efc9e686 --- /dev/null +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -0,0 +1,43 @@ +import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; +import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/pb_shared_master_node.dart'; +import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_intermediate_node.dart'; +import 'package:recase/recase.dart'; + +class MiddlewareUtils { + static String generateChangeNotifierClass( + String states, + String defaultStateName, + PBGenerationManager manager, + String defaultWidgetName, { + List overrideProperties, + }) { + var overrideVars = ''; // Variables outside of initializer + var overrideAttr = ''; // Attributes that will be part of initializer + + overrideProperties?.forEach((property) { + overrideVars += 'final ${property.friendlyName};'; + overrideAttr += 'this.${property.friendlyName}, '; + }); + + return ''' + import 'package:flutter/material.dart'; + class ${defaultStateName} extends ChangeNotifier { + ${states} + ${overrideVars} + + Widget defaultWidget; + ${defaultStateName}({$overrideAttr}){ + defaultWidget = ${defaultWidgetName}; + } + } + '''; + } + + static String generateVariable(PBIntermediateNode node) { + return 'var ${node.name.camelCase} = ' + + node?.generator?.generate(node ?? '', + GeneratorContext(sizingContext: SizingValueContext.PointValue)) + + ';'; + } +} From 98ddf5b82d1f31782c47dc52655b5eb2b5eb9c8f Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 16 Feb 2021 22:19:28 -0500 Subject: [PATCH 08/16] Added usage of middleware utils to Provider and riverpod Provider and riverpod now generate overrideProps of symbol master --- .../state_management/provider_middleware.dart | 38 ++++++------------ .../state_management/riverpod_middleware.dart | 39 ++++++------------- 2 files changed, 23 insertions(+), 54 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 38d6cfe4..e78c63b8 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -1,5 +1,5 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/middleware/middleware.dart'; +import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.dart'; @@ -45,42 +45,26 @@ class ProviderMiddleware extends Middleware { // Iterating through states var stateBuffer = StringBuffer(); - stateBuffer.write(_generateProviderVariable(node)); + stateBuffer.write(MiddlewareUtils.generateVariable(node)); node.auxiliaryData.stateGraph.states.forEach((state) async { var variationNode = state.variation.node; - stateBuffer.write(_generateProviderVariable(variationNode)); + stateBuffer.write(MiddlewareUtils.generateVariable(variationNode)); }); - var code = _generateProviderClass(stateBuffer.toString(), watcherName, - generationManager, node.name.camelCase); + var code = MiddlewareUtils.generateChangeNotifierClass( + stateBuffer.toString(), + watcherName, + generationManager, + node.name.camelCase, + overrideProperties: + node is PBSharedMasterNode ? node.overridableProperties : [], + ); fileStrategy.writeProviderModelFile(code, getName(node.name).snakeCase); return node; } - String _generateProviderClass(String states, String defaultStateName, - PBGenerationManager manager, String defaultWidgetName) { - return ''' - import 'package:flutter/material.dart'; - class ${defaultStateName} extends ChangeNotifier { - ${states} - - Widget defaultWidget; - ${defaultStateName}(){ - defaultWidget = ${defaultWidgetName}; - } - } - '''; - } - - String _generateProviderVariable(PBIntermediateNode node) { - return 'var ${node.name.camelCase} = ' + - node?.generator?.generate(node ?? '', - GeneratorContext(sizingContext: SizingValueContext.PointValue)) + - ';'; - } - String getImportPath(PBSharedInstanceIntermediateNode node, fileStrategy) { var symbolMaster = PBSymbolStorage().getSharedMasterNodeBySymbolID(node.SYMBOL_ID); diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index c202c7cd..81a9bb3d 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -1,7 +1,9 @@ import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; +import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.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/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import '../../pb_generation_manager.dart'; @@ -39,45 +41,28 @@ class RiverpodMiddleware extends Middleware { return node; } watcherName = getNameOfNode(node); - // Iterating through states var stateBuffer = StringBuffer(); - stateBuffer.write(_generateProviderVariable(node)); + stateBuffer.write(MiddlewareUtils.generateVariable(node)); node.auxiliaryData.stateGraph.states.forEach((state) async { var variationNode = state.variation.node; - stateBuffer.write(_generateProviderVariable(variationNode)); + stateBuffer.write(MiddlewareUtils.generateVariable(variationNode)); }); - var code = _generateRiverpodClass(stateBuffer.toString(), watcherName, - generationManager, node.name.camelCase); + var code = MiddlewareUtils.generateChangeNotifierClass( + stateBuffer.toString(), + watcherName, + generationManager, + node.name.camelCase, + overrideProperties: + node is PBSharedMasterNode ? node.overridableProperties : [], + ); fileStrategy.writeRiverpodModelFile(code, getName(node.name).snakeCase); return node; } - String _generateRiverpodClass(String states, String defaultStateName, - PBGenerationManager manager, String defaultWidgetName) { - return ''' - import 'package:flutter/material.dart'; - class ${defaultStateName} extends ChangeNotifier { - ${states} - - Widget defaultWidget; - ${defaultStateName}(){ - defaultWidget = ${defaultWidgetName}; - } - } - '''; - } - - String _generateProviderVariable(PBIntermediateNode node) { - return 'var ${node.name.camelCase} = ' + - node?.generator?.generate(node ?? '', - GeneratorContext(sizingContext: SizingValueContext.PointValue)) + - ';'; - } - String getConsumer(String name) { return ''' Consumer( From 2fe4ed071f56e3b9c7b74b79a475ce2b9543beb3 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 16 Feb 2021 22:36:45 -0500 Subject: [PATCH 09/16] Provider and Riverpod add overrideProperties for their states --- .../state_management/provider_middleware.dart | 10 +++++++--- .../state_management/riverpod_middleware.dart | 10 ++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index e78c63b8..8a998d36 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -23,7 +23,7 @@ class ProviderMiddleware extends Middleware { var managerData = node.managerData; var fileStrategy = node.currentContext.project.fileStructureStrategy as ProviderFileStructureStrategy; - + var overrideProps = []; if (node is PBSharedInstanceIntermediateNode) { node.currentContext.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); @@ -41,6 +41,7 @@ class ProviderMiddleware extends Middleware { watcherName = getNameOfNode(node); if (node is PBSharedMasterNode) { node.name = watcherName; + overrideProps.addAll(node.overridableProperties ?? []); } // Iterating through states @@ -49,6 +50,10 @@ class ProviderMiddleware extends Middleware { node.auxiliaryData.stateGraph.states.forEach((state) async { var variationNode = state.variation.node; + if (variationNode is PBSharedMasterNode) { + overrideProps.addAll(variationNode.overridableProperties ?? []); + } + stateBuffer.write(MiddlewareUtils.generateVariable(variationNode)); }); @@ -57,8 +62,7 @@ class ProviderMiddleware extends Middleware { watcherName, generationManager, node.name.camelCase, - overrideProperties: - node is PBSharedMasterNode ? node.overridableProperties : [], + overrideProperties: overrideProps, ); fileStrategy.writeProviderModelFile(code, getName(node.name).snakeCase); diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 81a9bb3d..76f69cf1 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -24,6 +24,7 @@ class RiverpodMiddleware extends Middleware { var managerData = node.managerData; var fileStrategy = node.currentContext.project.fileStructureStrategy as RiverpodFileStructureStrategy; + var overrideProps = []; if (node is PBSharedInstanceIntermediateNode) { node.currentContext.project.genProjectData @@ -39,6 +40,8 @@ class RiverpodMiddleware extends Middleware { node.generator = StringGeneratorAdapter(getConsumer(watcherName)); return node; + } else if (node is PBSharedMasterNode) { + overrideProps.addAll(node.overridableProperties ?? []); } watcherName = getNameOfNode(node); // Iterating through states @@ -47,6 +50,10 @@ class RiverpodMiddleware extends Middleware { node.auxiliaryData.stateGraph.states.forEach((state) async { var variationNode = state.variation.node; + if (variationNode is PBSharedMasterNode) { + overrideProps.addAll(variationNode.overridableProperties ?? []); + } + stateBuffer.write(MiddlewareUtils.generateVariable(variationNode)); }); @@ -55,8 +62,7 @@ class RiverpodMiddleware extends Middleware { watcherName, generationManager, node.name.camelCase, - overrideProperties: - node is PBSharedMasterNode ? node.overridableProperties : [], + overrideProperties: overrideProps, ); fileStrategy.writeRiverpodModelFile(code, getName(node.name).snakeCase); From 9d94c5c7554e0f7f97cdc1b671a38b931fbeb68c Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 16 Feb 2021 23:34:32 -0500 Subject: [PATCH 10/16] States with override properties generate inside model initializer --- .../state_management/provider_middleware.dart | 23 +------ .../state_management/riverpod_middleware.dart | 21 +------ .../utils/middleware_utils.dart | 63 ++++++++++++++----- 3 files changed, 51 insertions(+), 56 deletions(-) diff --git a/lib/generation/generators/middleware/state_management/provider_middleware.dart b/lib/generation/generators/middleware/state_management/provider_middleware.dart index 8a998d36..679f1249 100644 --- a/lib/generation/generators/middleware/state_management/provider_middleware.dart +++ b/lib/generation/generators/middleware/state_management/provider_middleware.dart @@ -4,7 +4,6 @@ import 'package:parabeac_core/generation/generators/pb_generation_manager.dart'; import 'package:parabeac_core/generation/generators/pb_variable.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/provider_file_structure_strategy.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_symbol_storage.dart'; import 'package:recase/recase.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.dart'; @@ -23,7 +22,6 @@ class ProviderMiddleware extends Middleware { var managerData = node.managerData; var fileStrategy = node.currentContext.project.fileStructureStrategy as ProviderFileStructureStrategy; - var overrideProps = []; if (node is PBSharedInstanceIntermediateNode) { node.currentContext.project.genProjectData .addDependencies(PACKAGE_NAME, PACKAGE_VERSION); @@ -39,30 +37,11 @@ class ProviderMiddleware extends Middleware { return node; } watcherName = getNameOfNode(node); - if (node is PBSharedMasterNode) { - node.name = watcherName; - overrideProps.addAll(node.overridableProperties ?? []); - } - - // Iterating through states - var stateBuffer = StringBuffer(); - stateBuffer.write(MiddlewareUtils.generateVariable(node)); - node.auxiliaryData.stateGraph.states.forEach((state) async { - var variationNode = state.variation.node; - - if (variationNode is PBSharedMasterNode) { - overrideProps.addAll(variationNode.overridableProperties ?? []); - } - - stateBuffer.write(MiddlewareUtils.generateVariable(variationNode)); - }); var code = MiddlewareUtils.generateChangeNotifierClass( - stateBuffer.toString(), watcherName, generationManager, - node.name.camelCase, - overrideProperties: overrideProps, + node, ); fileStrategy.writeProviderModelFile(code, getName(node.name).snakeCase); diff --git a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart index 76f69cf1..004cc7ea 100644 --- a/lib/generation/generators/middleware/state_management/riverpod_middleware.dart +++ b/lib/generation/generators/middleware/state_management/riverpod_middleware.dart @@ -1,9 +1,7 @@ -import 'package:parabeac_core/generation/generators/attribute-helper/pb_generator_context.dart'; import 'package:parabeac_core/generation/generators/middleware/state_management/utils/middleware_utils.dart'; import 'package:parabeac_core/generation/generators/value_objects/file_structure_strategy.dart/riverpod_file_structure_strategy.dart'; import 'package:parabeac_core/generation/generators/value_objects/generator_adapter.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/entities/subclasses/pb_intermediate_node.dart'; import 'package:parabeac_core/interpret_and_optimize/helpers/pb_symbol_storage.dart'; import '../../pb_generation_manager.dart'; @@ -24,7 +22,6 @@ class RiverpodMiddleware extends Middleware { var managerData = node.managerData; var fileStrategy = node.currentContext.project.fileStructureStrategy as RiverpodFileStructureStrategy; - var overrideProps = []; if (node is PBSharedInstanceIntermediateNode) { node.currentContext.project.genProjectData @@ -40,29 +37,13 @@ class RiverpodMiddleware extends Middleware { node.generator = StringGeneratorAdapter(getConsumer(watcherName)); return node; - } else if (node is PBSharedMasterNode) { - overrideProps.addAll(node.overridableProperties ?? []); } watcherName = getNameOfNode(node); - // Iterating through states - var stateBuffer = StringBuffer(); - stateBuffer.write(MiddlewareUtils.generateVariable(node)); - node.auxiliaryData.stateGraph.states.forEach((state) async { - var variationNode = state.variation.node; - - if (variationNode is PBSharedMasterNode) { - overrideProps.addAll(variationNode.overridableProperties ?? []); - } - - stateBuffer.write(MiddlewareUtils.generateVariable(variationNode)); - }); var code = MiddlewareUtils.generateChangeNotifierClass( - stateBuffer.toString(), watcherName, generationManager, - node.name.camelCase, - overrideProperties: overrideProps, + node, ); fileStrategy.writeRiverpodModelFile(code, getName(node.name).snakeCase); diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index efc9e686..2b9beca5 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -6,38 +6,73 @@ import 'package:recase/recase.dart'; class MiddlewareUtils { static String generateChangeNotifierClass( - String states, String defaultStateName, PBGenerationManager manager, - String defaultWidgetName, { - List overrideProperties, - }) { + PBIntermediateNode node, + ) { var overrideVars = ''; // Variables outside of initializer var overrideAttr = ''; // Attributes that will be part of initializer + var stateInitializers = StringBuffer(); + var stateBuffer = StringBuffer(); - overrideProperties?.forEach((property) { - overrideVars += 'final ${property.friendlyName};'; - overrideAttr += 'this.${property.friendlyName}, '; + if (node is PBSharedMasterNode && + (node.overridableProperties?.isNotEmpty ?? false)) { + node.overridableProperties.forEach((property) { + overrideVars += 'final ${property.friendlyName};'; + overrideAttr += 'this.${property.friendlyName}, '; + }); + stateBuffer.write(MiddlewareUtils.generateEmptyVariable(node)); + stateInitializers.write( + '${node.name.camelCase} = ${MiddlewareUtils.generateVariableBody(node)}'); + } else { + stateBuffer.write(MiddlewareUtils.generateVariable(node)); + } + node?.auxiliaryData?.stateGraph?.states?.forEach((state) { + var variationNode = state.variation.node; + + if (variationNode is PBSharedMasterNode && + (variationNode.overridableProperties?.isNotEmpty ?? false)) { + variationNode.overridableProperties.forEach((property) { + overrideVars += 'final ${property.friendlyName};'; + overrideAttr += 'this.${property.friendlyName}, '; + }); + stateBuffer.write(MiddlewareUtils.generateEmptyVariable(variationNode)); + stateInitializers.write( + '${variationNode.name.camelCase} = ${MiddlewareUtils.generateVariableBody(variationNode)}'); + } else { + stateBuffer.write(MiddlewareUtils.generateVariable(variationNode)); + } }); return ''' import 'package:flutter/material.dart'; class ${defaultStateName} extends ChangeNotifier { - ${states} + ${stateBuffer.toString()} ${overrideVars} Widget defaultWidget; ${defaultStateName}({$overrideAttr}){ - defaultWidget = ${defaultWidgetName}; + + ${stateInitializers} + + defaultWidget = ${node.name.camelCase}; } } '''; } - static String generateVariable(PBIntermediateNode node) { - return 'var ${node.name.camelCase} = ' + - node?.generator?.generate(node ?? '', - GeneratorContext(sizingContext: SizingValueContext.PointValue)) + - ';'; + static String generateVariable(PBIntermediateNode node, + {String type = 'var'}) { + return '${type} ${node.name.camelCase} = ' + generateVariableBody(node); } + + static String generateEmptyVariable(PBIntermediateNode node, + {String type = 'var'}) => + '${type} ${node.name.camelCase};'; + + static String generateVariableBody(node) => + (node?.generator?.generate(node ?? '', + GeneratorContext(sizingContext: SizingValueContext.PointValue)) ?? + '') + + ';'; } From 1de298450bc1d986820c21b87712d111d1fc2c06 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Tue, 16 Feb 2021 23:43:05 -0500 Subject: [PATCH 11/16] Fixed Middleware not generating states with no override properties incorrectly --- .../middleware/state_management/utils/middleware_utils.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 2b9beca5..b8277eab 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -51,7 +51,7 @@ class MiddlewareUtils { ${overrideVars} Widget defaultWidget; - ${defaultStateName}({$overrideAttr}){ + ${defaultStateName}(${overrideAttr.isNotEmpty ? (overrideAttr) : ''}){ ${stateInitializers} From 9be9fb5db645d40510c89dfb8b8fb9deffc39b43 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Wed, 17 Feb 2021 21:27:34 -0500 Subject: [PATCH 12/16] Made override values optional --- .../middleware/state_management/utils/middleware_utils.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index b8277eab..176f384f 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -51,7 +51,7 @@ class MiddlewareUtils { ${overrideVars} Widget defaultWidget; - ${defaultStateName}(${overrideAttr.isNotEmpty ? (overrideAttr) : ''}){ + ${defaultStateName}(${overrideAttr.isNotEmpty ? ('\{' + overrideAttr + '\}') : ''}){ ${stateInitializers} From 7850c97c438d7c3f20e3fd203e125a47cacd1edf Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 18 Feb 2021 18:37:58 -0500 Subject: [PATCH 13/16] Changed imports to Set. Using manager to generate imports instead of writing them directly for bloc, provider, riverpod. --- .../flutter_project_builder/import_helper.dart | 10 ++++++---- .../middleware/state_management/bloc_middleware.dart | 12 ++++++------ .../state_management/utils/middleware_utils.dart | 9 +++------ lib/generation/generators/pb_flutter_generator.dart | 1 - .../pb_generation_configuration.dart | 1 + .../provider_generation_configuration.dart | 2 +- .../riverpod_generation_configuration.dart | 2 +- .../generators/writers/pb_flutter_writer.dart | 2 +- 8 files changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/generation/flutter_project_builder/import_helper.dart b/lib/generation/flutter_project_builder/import_helper.dart index 39e830cf..f0965d47 100644 --- a/lib/generation/flutter_project_builder/import_helper.dart +++ b/lib/generation/flutter_project_builder/import_helper.dart @@ -10,9 +10,11 @@ import 'package:parabeac_core/interpret_and_optimize/helpers/pb_gen_cache.dart'; class ImportHelper { /// Traverse the [node] tree, check if any nodes need importing, /// and add the relative import from [path] to the [node] - static List findImports(PBIntermediateNode node, String path) { - List imports = []; - if (node == null) return imports; + static Set findImports(PBIntermediateNode node, String path) { + Set imports = {}; + if (node == null) { + return imports; + } String id; if (node is PBSharedInstanceIntermediateNode) { @@ -49,6 +51,6 @@ class ImportHelper { imports.addAll(findImports(node.child, path)); } - return imports.toSet().toList(); // Prevent repeated entries + return imports; } } diff --git a/lib/generation/generators/middleware/state_management/bloc_middleware.dart b/lib/generation/generators/middleware/state_management/bloc_middleware.dart index 3d9af771..84fc38cd 100644 --- a/lib/generation/generators/middleware/state_management/bloc_middleware.dart +++ b/lib/generation/generators/middleware/state_management/bloc_middleware.dart @@ -81,8 +81,12 @@ class BLoCMiddleware extends Middleware { ); /// Creates bloc page + managerData.addImport('package:meta/meta.dart'); await fileStrategy.generatePage( - _createBlocPage(parentState, node.name), + _createBlocPage( + parentState, + node.name, + ), '${parentDirectory}/${generalName}_bloc', args: 'VIEW', ); @@ -94,11 +98,7 @@ class BLoCMiddleware extends Middleware { var pascalName = name.pascalCase; var snakeName = name.snakeCase; return ''' - import 'dart:async'; - - import 'package:flutter_bloc/flutter_bloc.dart'; - import 'package:meta/meta.dart'; - import 'package:flutter/material.dart'; + ${generationManager.generateImports()} part '${snakeName}_event.dart'; part '${snakeName}_state.dart'; diff --git a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart index 176f384f..446709b8 100644 --- a/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart +++ b/lib/generation/generators/middleware/state_management/utils/middleware_utils.dart @@ -5,11 +5,8 @@ import 'package:parabeac_core/interpret_and_optimize/entities/subclasses/pb_inte import 'package:recase/recase.dart'; class MiddlewareUtils { - static String generateChangeNotifierClass( - String defaultStateName, - PBGenerationManager manager, - PBIntermediateNode node, - ) { + static String generateChangeNotifierClass(String defaultStateName, + PBGenerationManager manager, PBIntermediateNode node) { var overrideVars = ''; // Variables outside of initializer var overrideAttr = ''; // Attributes that will be part of initializer var stateInitializers = StringBuffer(); @@ -45,7 +42,7 @@ class MiddlewareUtils { }); return ''' - import 'package:flutter/material.dart'; + ${manager.generateImports()} class ${defaultStateName} extends ChangeNotifier { ${stateBuffer.toString()} ${overrideVars} diff --git a/lib/generation/generators/pb_flutter_generator.dart b/lib/generation/generators/pb_flutter_generator.dart index 92fbd078..f771c87e 100644 --- a/lib/generation/generators/pb_flutter_generator.dart +++ b/lib/generation/generators/pb_flutter_generator.dart @@ -73,7 +73,6 @@ class PBFlutterGenerator extends PBGenerationManager { @override String generateImports() { var buffer = StringBuffer(); - buffer.write('import \'package:flutter/material.dart\';\n'); var it = data.imports; while (it.moveNext()) { buffer.write('import \'${it.current}\';\n'); diff --git a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart index 235467da..2b119d4e 100644 --- a/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/pb_generation_configuration.dart @@ -105,6 +105,7 @@ abstract class GenerationConfiguration { await setUpConfiguration(); pbProject.fileStructureStrategy = fileStructureStrategy; for (var tree in pbProject.forest) { + tree.data.addImport('package:flutter/material.dart'); _generationManager.data = tree.data; var fileName = tree.rootNode?.name?.snakeCase ?? 'no_name_found'; if (tree.rootNode is InheritedScaffold && diff --git a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart index 95649c58..476a567c 100644 --- a/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/provider_generation_configuration.dart @@ -29,7 +29,7 @@ class ProviderGenerationConfiguration extends GenerationConfiguration { Future generateProject(PBProject pb_project) async { await super.generateProject(pb_project); if (pageWriter is PBFlutterWriter) { - var imports = ['import \'package:provider/provider.dart\';']; + Set imports = {'import \'package:provider/provider.dart\';'}; imports.addAll(registeredModels .map((e) => 'import \'models/${e.snakeCase}.dart\';') .toList()); diff --git a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart index d402aa6d..407fffa5 100644 --- a/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart +++ b/lib/generation/generators/value_objects/generation_configuration/riverpod_generation_configuration.dart @@ -27,7 +27,7 @@ class RiverpodGenerationConfiguration extends GenerationConfiguration { (pageWriter as PBFlutterWriter).rewriteMainFunction( fileStructureStrategy.GENERATED_PROJECT_PATH + 'lib/main.dart', _generateMainFunction(), - imports: ["import 'package:flutter_riverpod/flutter_riverpod.dart';"], + imports: {"import 'package:flutter_riverpod/flutter_riverpod.dart';"}, ); } } diff --git a/lib/generation/generators/writers/pb_flutter_writer.dart b/lib/generation/generators/writers/pb_flutter_writer.dart index 7c1ee265..47b60313 100644 --- a/lib/generation/generators/writers/pb_flutter_writer.dart +++ b/lib/generation/generators/writers/pb_flutter_writer.dart @@ -26,7 +26,7 @@ class PBFlutterWriter implements PBPageWriter { /// Function that allows the rewriting of the main() method inside main.dart void rewriteMainFunction(String pathToMain, String code, - {List imports}) { + {Set imports}) { var mainRead = File(pathToMain).readAsStringSync(); var newMain = imports.join() + mainRead.replaceFirst( From 52c49896e54d3fd39f1e7d2c18ab501dc35f7c06 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Thu, 18 Feb 2021 18:45:18 -0500 Subject: [PATCH 14/16] Updated imports test to accomodate for imports being a set --- test/lib/generation/import_test.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/lib/generation/import_test.dart b/test/lib/generation/import_test.dart index f8fccd36..c1f9e737 100644 --- a/test/lib/generation/import_test.dart +++ b/test/lib/generation/import_test.dart @@ -47,9 +47,9 @@ void main() { iNodeWithImports, '/path/to/page/importer.dart'); expect(imports.length, 3); - expect(imports[0], './importee1.dart'); - expect(imports[1], '../importee2.dart'); - expect(imports[2], './sub/importee3.dart'); + expect(imports.contains('./importee1.dart'), true); + expect(imports.contains('../importee2.dart'), true); + expect(imports.contains('./sub/importee3.dart'), true); }); test('Testing import generation when no imports are generated', () { From 83dab0f032302eb0ecd0df3b37393ebc78f7edcf Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Sat, 20 Feb 2021 17:31:43 -0500 Subject: [PATCH 15/16] Added table of contents to readme. Added small segment to state management section. --- README.md | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f704396a..a147b83e 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,19 @@ Parabeac-Core is an open-source repository that converts design files into Flutt Debugging +# Table of Contents +1. [What is Parabeac-Core](#what-is-parabeac-core) +2. [Get Started](#get-started) + + 1. [Cloning the Repo](#cloning-the-repo) + 2. [Running the conversion](#running-the-conversion) + 3. [Metrics](#metrics) + 4. [Using State Management Configuration](#using-state-management-configuration) +3. [Running the exported Code](#running-the-exported-code) +4. [How to create & run Parabeac eggs](#how-to-create-&-run-parabeac-eggs) +5. [How it works](#how-it-works) +6. [How to contribute](#how-to-contribute) + # What is Parabeac-Core? Parabeac-Core is an open-source repository that converts design files into Flutter code. The biggest challenge in code conversion is achieving quality code, but in a tool like this, there’s so much variability in what quality code should look like. So Parabeac-Core is built in a way not to promise quality code, but to be driven by the community so that you can configure & tweak to you or your teams liking. See our [Manifesto](https://github.com/Parabeac/Parabeac-Core/blob/stable/MANIFESTO.md). We welcome contributors to improve Parabeac-Core, create [Parabeac Eggs](https://github.com/Parabeac/parabeac-egg-template), & to join our [Discord](https://discord.com/invite/qUrghes) community! @@ -100,7 +113,6 @@ Since Figma operates from a cloud native approach we use the Figma File ID and a 3. Scroll Down to the "Create a new Personal Access Token" 4. Create a new Personal Access Token with the name Parabeac, you should then be prompted with your new API Key. Make sure to copy this as you wont be able to access it again after you click confirm. (It should look something like this: ```64522-a0e5509a-d5ce-47a8-880b-c295f9cb27ed``` - ## Metrics Parabeac-core keeps track of how many times it is run. Although we do not collect any personal information, you can turn off metrics at any time by creating the environment variable `PB_METRICS = "false"`. @@ -123,11 +135,12 @@ To set the state management configuration, head over to edit `/Parabeac-Core/lib } ``` -Here you can replace the `state-management` property to `bloc` or `provider`. Soon you can also set `riverpod`. +Here you can replace the `state-management` property to `bloc`, `provider`, or `riverpod`. -You can learn how to easily create your own state management configuration in the [wiki](https://github.com/Parabeac/Parabeac-Core/wiki/How-to-Create-a-State-Management-Configuration), let us know if you're thinking about doing this and if you need any help! +For sample Sketch and Figma files you can use to test state management, please see [Get Started](#get-started) You can learn how to easily create your own state management configuration in the [wiki](https://github.com/Parabeac/Parabeac-Core/wiki/How-to-Create-a-State-Management-Configuration), let us know if you're thinking about doing this and if you need any help! + # Running the exported code ### Requirements - Flutter @@ -182,7 +195,6 @@ Depending on the type of layout to add alignment to we have various services to ![Parabeac Alignment Generation Service Animation](https://kindling-sketch.s3.amazonaws.com/parabeac-alignment-generation-service2.gif) - # How to contribute Welcome! The best way to contribute to Parabeac is through pull requests, filing issues on Github, writing documentation & helping others in our Discord community. We are an early project, but like many other projects, helping with bugs that others have filed on Stack Overflow is extremely helpful. We recommend filing bugs & feature requests on the Github issue tracker. For more details make sure to check out our [wiki](https://github.com/Parabeac/Parabeac-Core/wiki). From bdce9d738f4f97b094ea4f7cbac634bc4537dc46 Mon Sep 17 00:00:00 2001 From: Ivan Vigliante Date: Mon, 22 Feb 2021 00:16:41 -0500 Subject: [PATCH 16/16] Updated SAC to latest version --- SketchAssetConverter | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SketchAssetConverter b/SketchAssetConverter index 84e2a7b8..8e424654 160000 --- a/SketchAssetConverter +++ b/SketchAssetConverter @@ -1 +1 @@ -Subproject commit 84e2a7b84e61f201fe0bc0eba2843f9e32f7affb +Subproject commit 8e424654c1228ffd3a767a9c36555840a4583e09