frap 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a94c44eaae2cb515d4ae619672a6e2eed5d3e352c9ccceb60e49bc6123f2d2b
4
- data.tar.gz: 8e3f7a0d93b24ac0bb3ffdb5b2963cbb09e2c83c26e33d16970b88f194cc382b
3
+ metadata.gz: 2113fe87e979c5dcc6f1068901f9addbb33398ef7bbc54d138d87c37b3813145
4
+ data.tar.gz: 75f07d7ef133da72c45d1086b28e3054020a6aadeb889a5dc06ad90a2598a9f5
5
5
  SHA512:
6
- metadata.gz: e955d2a12647e5ba589f6d88baa5aa68c1105d4cb3618836ec9e60299286fede785f4d0fb190c47d516f4295a36409c6937e70e606ebebdb6593ce0ef706f96a
7
- data.tar.gz: ad972c11753fa6ecbaa24cb81c147d657650356a615909b6dd254678108daec5182643aafb23c596a50f9964f2738fd745f7afcd263eaf9428d9360b31b1d8c9
6
+ metadata.gz: 2199c30717694e927e1275b0c4c661302b7e1e6f04db69ba06b05f4cee4486aaf440340f0ad7aa85b96a364944d9f193c63dc23fd3f6d350c482f2fd5bb77e92
7
+ data.tar.gz: 93bdd37d1101b04848a6bdcd86cf69c89c2806548c53f2c54c07f0546d2b5374cc798dab578ecb267741e3021da42eeda80570f5ddfdb7210939fda28623e72d
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- frap (0.2.0)
4
+ frap (0.2.1)
5
5
  thor (~> 0.20.3)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -32,6 +32,30 @@ This will create a new Parent directory for the Rails and Flutter App.
32
32
  |__ my_app_server
33
33
  |__ my_app_ui
34
34
  ```
35
+ Generate a Rails and Flutter Resource from the app route directory `/my_app`, **currently does NOT support references, please open an ISSUE for broken data types**
36
+ `frap generate resource post -a title:string body:text`
37
+
38
+ The next step is to implement your Rails controller method for index action and run the migrations:
39
+ ```
40
+ cd my_app/my_app_server
41
+ rails db:migrate
42
+ ```
43
+ You can then edit the `app/constrollers/posts_controller.rb`:
44
+ ```ruby
45
+ class PostsController < ApplicationController
46
+ def index
47
+ render json: { posts: Post.all.as_json }, status: :ok
48
+ end
49
+ end
50
+ ```
51
+ Next fire up Rails and Flutter (you may need to start up an emulator, just follow the terminal output:
52
+ ```bash
53
+ cd my_app/my_app_server
54
+ rails s
55
+
56
+ cd my_app/my_app_ui
57
+ flutter run
58
+ ```
35
59
 
36
60
 
37
61
  ## Motivation
@@ -4,6 +4,7 @@ require 'frap/create_resource'
4
4
  require 'frap/commands/generate'
5
5
  require 'frap/generators/config'
6
6
  require 'frap/generators/flutter_config'
7
+ require 'frap/generators/flutter_resource'
7
8
  require 'thor'
8
9
  require 'yaml'
9
10
 
@@ -17,15 +17,16 @@ module Frap
17
17
  private
18
18
 
19
19
  def generate_rails_resource
20
- Dir.chdir("#{working_dir}/#{rails_app}")
21
-
20
+ Dir.chdir("#{working_dir}/#{rails_app_dir}")
22
21
  system("rails generate resource #{name} #{fields}")
22
+ Dir.chdir("#{working_dir}")
23
23
  end
24
24
 
25
25
  def generate_flutter_resource
26
- Dir.chdir("#{working_dir}/#{flutter_app}")
27
-
28
- puts "TODO: frap g flutter resource #{name} #{fields}"
26
+ flutter_fields = options[:attributes] || 'name:string'
27
+ Frap::Generators::FlutterResource.new(
28
+ [name.capitalize, flutter_app_dir, flutter_fields]
29
+ ).invoke(:configure_directories)
29
30
  end
30
31
 
31
32
  def fields
@@ -51,11 +52,11 @@ module Frap
51
52
  @config ||= YAML.load(File.read('config.yml'))
52
53
  end
53
54
 
54
- def flutter_app
55
+ def flutter_app_dir
55
56
  config['flutter_app']
56
57
  end
57
58
 
58
- def rails_app
59
+ def rails_app_dir
59
60
  config['rails_app']
60
61
  end
61
62
  end
@@ -28,6 +28,8 @@ module Frap
28
28
 
29
29
  def create_files
30
30
  template('main.dart.erb', "#{lib_directory}/main.dart")
31
+ template('src/constants/app_constants.dart.erb', "#{src_directory}/constants/app_constants.dart")
32
+ template('src/resources/repository.dart.erb', "#{src_directory}/resources/repository.dart")
31
33
  template('src/app.dart.erb', "#{src_directory}/app.dart")
32
34
  template('src/animations/slide_right_route.dart.erb', "#{src_directory}/animations/slide_right_route.dart")
33
35
  template('src/config/router.dart.erb', "#{src_directory}/config/router.dart")
@@ -44,7 +46,7 @@ module Frap
44
46
  def setup_pages
45
47
  inject_into_file("#{src_directory}/config/router.dart", home_router, after: /^.*switch \(settings.name\) \{$/)
46
48
  inject_into_file("#{src_directory}/constants/pages_list.dart", home_route, after: /const List<Page> pages = const <Page>\[.*$/)
47
- append_to_file("#{src_directory}/constants/routing.dart", "const String HomeScreenRoute = '/';")
49
+ append_to_file("#{src_directory}/constants/routing.dart", "const String HomeScreenRoute = '/';\n")
48
50
  end
49
51
 
50
52
  private
@@ -65,7 +67,8 @@ module Frap
65
67
  %Q(
66
68
  dio: ^2.1.13
67
69
  rxdart: ^0.22.0
68
- bloc_pattern: ^2.2.3)
70
+ bloc_pattern: ^2.2.3
71
+ http: ^0.12.0+2)
69
72
  end
70
73
 
71
74
  def home_router
@@ -76,7 +79,8 @@ module Frap
76
79
 
77
80
  def home_route
78
81
  %Q(
79
- const Page(title: 'Home', icon: Icons.home, route: HomeScreenRoute),)
82
+ const Page(title: 'Home', icon: Icons.home, route: HomeScreenRoute),
83
+ )
80
84
  end
81
85
  end
82
86
  end
@@ -1,3 +1,5 @@
1
+ require 'active_support/inflector'
2
+
1
3
  module Frap
2
4
  module Generators
3
5
  class FlutterResource < Thor::Group
@@ -5,37 +7,82 @@ module Frap
5
7
 
6
8
  desc 'Generate Flutter Config files'
7
9
  argument :name
8
- argument :folder_name
9
-
10
+ argument :flutter_app_dir
11
+ argument :fields
10
12
  def self.source_root
11
13
  File.dirname(__FILE__) + '/templates/dart'
12
14
  end
13
15
 
14
16
  def configure_directories
15
- inject_into_file("#{working_directory}/pubspec.yaml", pub_files, after: /^dependencies:.*$/)
16
- remove_file("#{lib_directory}/main.dart")
17
17
  invoke :create_directories
18
18
  end
19
19
 
20
20
  def create_directories
21
- empty_directory("#{lib_directory}/src/home")
21
+ empty_directory("#{lib_directory}/src/screens/#{lower_name}")
22
+
22
23
  invoke :create_files
23
24
  end
24
25
 
25
26
  def create_files
26
- template('main.dart.erb', "#{lib_directory}/main.dart")
27
- template('src/app_bloc.dart.erb', "#{src_directory}/app_bloc.dart")
28
- template('src/app_module.dart.erb', "#{src_directory}/app_module.dart")
29
- template('src/app_widget.dart.erb', "#{src_directory}/app_widget.dart")
30
- template('src/home/home_bloc.dart.erb', "#{src_directory}/home/home_bloc.dart")
31
- template('src/home/home_module.dart.erb', "#{src_directory}/home/home_module.dart")
32
- template('src/home/home_page.dart.erb', "#{src_directory}/home/home_page.dart")
27
+ @name_capitalized_plural = name_capitalize_pluralize
28
+ @name_capitalized_single = name_capitalized_single
29
+ @name_downcased_plural = name_downcase_pluralize
30
+ @lower_name = lower_name
31
+ @field_types = build_fields
32
+ @field_names = fields.keys
33
+ template('src/screens/base_index.dart.erb', "#{screen_path}/#{lower_name}_index_screen.dart")
34
+ template('src/screens/base_bottom_navigation.dart.erb', "#{screen_path}/#{lower_name}_show_screen.dart")
35
+ template('src/blocs/base_block.dart.erb', "#{src_directory}/blocs/#{@name_downcased_plural}_bloc.dart")
36
+ template('src/models/base_model.dart.erb', "#{src_directory}/models/#{@name_downcased_plural}.dart")
37
+ template('src/resources/base_api_provider.dart.erb', "#{src_directory}/resources/#{lower_name}_api_provider.dart")
38
+ invoke :connect_widgets
39
+ end
40
+
41
+ def connect_widgets
42
+ inject_into_file("#{src_directory}/config/router.dart", router_packages, after: /^import 'package:flutter\/material.dart';$/)
43
+ inject_into_file("#{src_directory}/config/router.dart", show_screen_router, after: /^.*switch \(settings.name\) \{$/)
44
+ inject_into_file("#{src_directory}/config/router.dart", index_screen_router, after: /^.*switch \(settings.name\) \{$/)
45
+ inject_into_file("#{src_directory}/constants/pages_list.dart", index_screen_route, after: /const List<Page> pages = const <Page>\[.*$/)
46
+ inject_into_file("#{src_directory}/resources/repository.dart", repository_packages, after: /^import 'dart:async';$/)
47
+ inject_into_file("#{src_directory}/resources/repository.dart", repository_body, after: /^class Repository \{$/)
48
+ append_to_file("#{src_directory}/constants/routing.dart", "const String #{name}IndexScreenRoute = '/#{lower_name.pluralize }'; \n")
49
+ append_to_file("#{src_directory}/constants/routing.dart", "const String #{name}ShowScreenRoute = '/#{lower_name.singularize}';\n")
50
+ # Here we will make sure all imports are handled:
51
+ # Import new resource into routes route and constants
52
+ # Index page with bottom floating button for adding
53
+ # build detail screen with bottom navigations
54
+ # Link navigation buttons to Edit and back to list and delete
33
55
  end
34
56
 
35
57
  private
36
58
 
59
+ def build_fields
60
+ return unless fields
61
+
62
+ fields.map do |key, value|
63
+ case value
64
+ when 'text'
65
+ "String #{key}"
66
+ when 'string'
67
+ "String #{key}"
68
+ when 'integer'
69
+ "int #{key}"
70
+ when 'float'
71
+ "double #{key}"
72
+ when 'bigint'
73
+ "BigInt #{key}"
74
+ when 'datetime'
75
+ "DateTime #{key}"
76
+ when 'boolean'
77
+ "bool #{key}"
78
+ else
79
+ "var #{key}"
80
+ end
81
+ end
82
+ end
83
+
37
84
  def working_directory
38
- "#{destination_root}/#{folder_name}"
85
+ "#{destination_root}/#{flutter_app_dir}"
39
86
  end
40
87
 
41
88
  def lib_directory
@@ -46,11 +93,64 @@ module Frap
46
93
  "#{lib_directory}/src"
47
94
  end
48
95
 
49
- def pub_files
96
+ def screen_path
97
+ "#{src_directory}/screens/#{lower_name}"
98
+ end
99
+
100
+ def index_screen_router
101
+ %Q(
102
+ case #{name}IndexScreenRoute:
103
+ return SlideRightRoute(widget:#{name}IndexScreen());)
104
+ end
105
+
106
+ def index_screen_route
50
107
  %Q(
51
- dio: ^2.1.13
52
- rxdart: ^0.22.0
53
- bloc_pattern: ^2.2.3)
108
+ const Page(title: '#{name.pluralize}', icon: Icons.home, route: #{name}IndexScreenRoute),)
109
+ end
110
+
111
+ def show_screen_router
112
+ %Q(
113
+ case #{name}ShowScreenRoute:
114
+ return SlideRightRoute(widget:#{name}ShowScreen());)
115
+ end
116
+
117
+ def show_screen_route
118
+ %Q(
119
+ const Page(title: '#{name}', icon: Icons.home, route: #{name}ShowScreenRoute),)
120
+ end
121
+
122
+ def lower_name
123
+ name.downcase.singularize
124
+ end
125
+
126
+ def name_capitalized_single
127
+ name.capitalize.singularize
128
+ end
129
+
130
+ def name_capitalize_pluralize
131
+ name.capitalize.pluralize
132
+ end
133
+
134
+ def name_downcase_pluralize
135
+ name.downcase.pluralize
136
+ end
137
+
138
+ def router_packages
139
+ %Q(
140
+ import 'package:#{flutter_app_dir}/src/screens/#{lower_name}/#{lower_name}_index_screen.dart';
141
+ import 'package:#{flutter_app_dir}/src/screens/#{lower_name}/#{lower_name}_show_screen.dart';)
142
+ end
143
+
144
+ def repository_body
145
+ %Q(
146
+ final #{lower_name}ApiProvider = #{name_capitalized_single}ApiProvider();
147
+ Future<#{name_capitalize_pluralize}> fetchAll#{name_capitalize_pluralize}() => #{lower_name}ApiProvider.fetchAll#{name_capitalize_pluralize}();)
148
+ end
149
+
150
+ def repository_packages
151
+ %Q(
152
+ import 'package:#{flutter_app_dir}/src/resources/#{lower_name}_api_provider.dart';
153
+ import 'package:#{flutter_app_dir}/src/models/#{name_downcase_pluralize}.dart';)
54
154
  end
55
155
  end
56
156
  end
@@ -5,10 +5,9 @@ import 'package:<%= folder_name %>/src/config/router.dart' as router;
5
5
  import 'package:<%= folder_name %>/src/constants/routing.dart';
6
6
 
7
7
  class App extends StatelessWidget {
8
- @override
9
-
10
8
  static const String _title = '<%= folder_name %>';
11
9
 
10
+ @override
12
11
  Widget build(BuildContext context) {
13
12
  return MaterialApp(
14
13
  title: _title,
@@ -0,0 +1,21 @@
1
+ import 'package:rxdart/rxdart.dart';
2
+ import 'package:<%= flutter_app_dir %>/src/resources/repository.dart';
3
+ import 'package:<%= flutter_app_dir %>/src/models/<%= @name_downcased_plural %>.dart';
4
+
5
+ class <%= @name_capitalized_plural %>Bloc {
6
+ final _repository = Repository();
7
+ final _<%= @name_downcased_plural %>Fetcher = PublishSubject<<%= @name_capitalized_plural %>>();
8
+
9
+ Observable<<%= @name_capitalized_plural %>> get all<%= @name_capitalized_plural %> => _<%= @name_downcased_plural %>Fetcher.stream;
10
+
11
+ fetchAll<%= @name_capitalized_plural %>() async {
12
+ <%= @name_capitalized_plural %> <%= @name_downcased_plural %> = await _repository.fetchAll<%= @name_capitalized_plural %>();
13
+ _<%= @name_downcased_plural%>Fetcher.sink.add(<%= @name_downcased_plural %>);
14
+ }
15
+
16
+ dispose() {
17
+ _<%= @name_downcased_plural %>Fetcher.close();
18
+ }
19
+ }
20
+
21
+ final bloc = <%= @name_capitalized_plural %>Bloc();
@@ -1,5 +1,4 @@
1
1
  import 'package:flutter/material.dart';
2
-
3
2
  import 'package:<%= folder_name %>/src/animations/slide_right_route.dart';
4
3
  import 'package:<%= folder_name %>/src/constants/routing.dart';
5
4
  import 'package:<%= folder_name %>/src/screens/home_screen.dart';
@@ -0,0 +1 @@
1
+ const String RootUrl = 'http://10.0.2.2:3000';
@@ -0,0 +1,32 @@
1
+ class <%= @name_capitalized_plural %> {
2
+ int _id;
3
+ List<<%= @name_capitalized_single %>> _results = [];
4
+
5
+ <%= @name_capitalized_plural %>.fromJson(Map<String, dynamic> parsedJson) {
6
+ List<<%= @name_capitalized_single %>> temp = [];
7
+ for (int i = 0; i < parsedJson['<%= @name_downcased_plural %>'].length; i++) {
8
+ <%= @name_capitalized_single %> result = <%= @name_capitalized_single %>.fromJson(parsedJson['<%= @name_downcased_plural %>'][i]);
9
+ temp.add(result);
10
+ }
11
+ _results = temp;
12
+ }
13
+
14
+ List<<%= @name_capitalized_single %>> get results => _results;
15
+ }
16
+
17
+ class <%= @name_capitalized_single %> {
18
+ <% @field_types.each do |field| %>final <%= field %>;
19
+ <% end %>
20
+
21
+ <%= @name_capitalized_single %>({
22
+ <% @field_names.each do |field| %>this.<%= field %>,
23
+ <% end %>
24
+ });
25
+
26
+ factory <%= @name_capitalized_single %>.fromJson(Map<String, dynamic> json) {
27
+ return <%= @name_capitalized_single %>(
28
+ <% @field_names.each do |field| %><%= field %>: json['<%= field %>'],
29
+ <% end %>
30
+ );
31
+ }
32
+ }
@@ -0,0 +1,18 @@
1
+ import 'dart:async';
2
+ import 'package:http/http.dart' as http;
3
+ import 'dart:convert';
4
+ import 'package:<%= flutter_app_dir %>/src/models/<%= @name_downcased_plural %>.dart';
5
+ import 'package:<%= flutter_app_dir %>/src/constants/app_constants.dart';
6
+
7
+ class <%= @name_capitalized_single %>ApiProvider {
8
+ Future<<%= @name_capitalized_plural %>> fetchAll<%= @name_capitalized_plural %>() async {
9
+ final response =
10
+ await http.get("${RootUrl}/<%= @name_downcased_plural %>");
11
+
12
+ if (response.statusCode == 200) {
13
+ return <%= @name_capitalized_plural %>.fromJson(json.decode(response.body));
14
+ } else {
15
+ throw Exception('Failed to load <%= @name_capitalized_plural %>');
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,4 @@
1
+ import 'dart:async';
2
+
3
+ class Repository {
4
+ }
@@ -1,5 +1,4 @@
1
1
  import 'package:flutter/material.dart';
2
- import 'package:<%= folder_name %>/src/constants/routing.dart';
3
2
  import 'package:<%= folder_name %>/src/widgets/base_app_bar.dart';
4
3
  import 'package:<%= folder_name %>/src/widgets/popup_menu_widget.dart';
5
4
 
@@ -0,0 +1,57 @@
1
+ import 'package:flutter/material.dart';
2
+ import 'package:<%= flutter_app_dir %>/src/widgets/base_app_bar.dart';
3
+ import 'package:<%= flutter_app_dir %>/src/widgets/popup_menu_widget.dart';
4
+ import 'package:<%= flutter_app_dir %>/src/screens/<%= name.downcase %>/<%= name.downcase %>_index_screen.dart';
5
+
6
+ class <%= name %>ShowScreen extends StatefulWidget {
7
+ <%= name %>ShowScreen({Key key}) : super(key: key);
8
+
9
+ @override
10
+ _<%= name %>ShowScreenState createState() => _<%= name %>ShowScreenState();
11
+ }
12
+
13
+ class _<%= name %>ShowScreenState extends State<<%= name %>ShowScreen> {
14
+ int _selectedIndex = 1;
15
+
16
+ final List<Widget> _widgets = <Widget>[
17
+ <%= name %>IndexScreen(),
18
+ ];
19
+
20
+ void _onItemTapped(int index) {
21
+ setState(() {
22
+ _selectedIndex = index;
23
+ });
24
+ }
25
+
26
+ @override
27
+
28
+ Widget build(BuildContext context) {
29
+ return Scaffold(
30
+ appBar: BaseAppBar(
31
+ title: Text('<%= name %>'),
32
+ appBar: AppBar(),
33
+ widgets: <Widget>[
34
+ PopupMenuWidget(),
35
+ ],
36
+ ),
37
+ body: Center(
38
+ child: Text('<%= name %>'),
39
+ ),
40
+ bottomNavigationBar: BottomNavigationBar(
41
+ items: const <BottomNavigationBarItem>[
42
+ BottomNavigationBarItem(
43
+ icon: Icon(Icons.dashboard),
44
+ title: Text('Back'),
45
+ ),
46
+ BottomNavigationBarItem(
47
+ icon: Icon(Icons.monetization_on),
48
+ title: Text('Edit'),
49
+ ),
50
+ ],
51
+ currentIndex: _selectedIndex,
52
+ selectedItemColor: Colors.green,
53
+ onTap: _onItemTapped,
54
+ ),
55
+ );
56
+ }
57
+ }
@@ -0,0 +1,72 @@
1
+ import 'package:flutter/material.dart';
2
+ import 'package:<%= flutter_app_dir %>/src/widgets/base_app_bar.dart';
3
+ import 'package:<%= flutter_app_dir %>/src/widgets/popup_menu_widget.dart';
4
+ import 'package:<%= flutter_app_dir %>/src/models/<%= @name_downcased_plural %>.dart';
5
+ import 'package:<%= flutter_app_dir %>/src/blocs/<%= @name_downcased_plural %>_bloc.dart';
6
+
7
+ class <%= @name_capitalized_single %>IndexScreen extends StatefulWidget {
8
+ @override
9
+ State<StatefulWidget> createState() {
10
+ return <%= @name_capitalized_single %>IndexScreenState();
11
+ }
12
+ }
13
+
14
+ class <%= @name_capitalized_single %>IndexScreenState extends State<<%= @name_capitalized_single %>IndexScreen> {
15
+ @override
16
+ void initState() {
17
+ super.initState();
18
+ bloc.fetchAll<%= @name_capitalized_plural %>();
19
+ }
20
+
21
+ // @override
22
+ // void dispose() {
23
+ // bloc.dispose();
24
+ // super.dispose();
25
+ // }
26
+
27
+ Widget build(BuildContext context) {
28
+ return Scaffold(
29
+ appBar: BaseAppBar(
30
+ title: Text('<%= @name_capitalized_single %>'),
31
+ appBar: AppBar(),
32
+ widgets: <Widget>[
33
+ PopupMenuWidget(),
34
+ ],
35
+ ),
36
+ body: StreamBuilder(
37
+ stream: bloc.all<%= @name_capitalized_plural %>,
38
+ builder: (context, AsyncSnapshot<<%= @name_capitalized_plural %>> snapshot) {
39
+ if (snapshot.hasData) {
40
+ return buildList(snapshot);
41
+ } else if (snapshot.hasError) {
42
+ return Text(snapshot.error.toString());
43
+ }
44
+ return Center(child: CircularProgressIndicator());
45
+ },
46
+ ),
47
+ floatingActionButton: FloatingActionButton(
48
+ elevation: 0.0,
49
+ child: Icon(Icons.add),
50
+ onPressed: (){ }
51
+ ),
52
+ );
53
+ }
54
+
55
+ Widget buildList(AsyncSnapshot<<%= @name_capitalized_plural %>> snapshot) {
56
+ return ListView.builder(
57
+ itemCount: snapshot.data.results.length,
58
+ itemBuilder: (BuildContext context, int index) {
59
+ return Card(
60
+ child: ListTile(
61
+ leading: Icon(Icons.map),
62
+ title: Text('TODO EDIT: snapshot.data.results[index].your_field_name'),
63
+ subtitle: Text('TODO EDIT: snapshot.data.results[index].your_field_name.toString()'),
64
+ trailing: Icon(Icons.more_vert),
65
+ onTap: () {},
66
+ )
67
+ );
68
+ },
69
+ );
70
+ }
71
+ }
72
+
@@ -1,6 +1,5 @@
1
1
  import 'package:flutter/material.dart';
2
2
  import 'package:<%= folder_name %>/src/constants/pages_list.dart';
3
- import 'package:<%= folder_name %>/src/constants/routing.dart';
4
3
 
5
4
  class PopupMenuWidget extends StatefulWidget {
6
5
  @override
@@ -8,12 +7,11 @@ class PopupMenuWidget extends StatefulWidget {
8
7
  }
9
8
 
10
9
  class _PopupMenuWidgetState extends State<PopupMenuWidget> {
11
- @override
12
-
13
10
  _onSelect(Page page) {
14
11
  Navigator.pushNamed(context, page.route);
15
12
  }
16
13
 
14
+ @override
17
15
  Widget build(BuildContext context) {
18
16
  return PopupMenuButton<Page>(
19
17
  onSelected: _onSelect,
@@ -1,3 +1,3 @@
1
1
  module Frap
2
- VERSION = "0.2.0"
2
+ VERSION = "0.2.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: frap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - James Gascoigne - Taylor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-29 00:00:00.000000000 Z
11
+ date: 2019-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -115,10 +115,20 @@ files:
115
115
  - lib/frap/generators/templates/dart/main.dart.erb
116
116
  - lib/frap/generators/templates/dart/src/animations/slide_right_route.dart.erb
117
117
  - lib/frap/generators/templates/dart/src/app.dart.erb
118
+ - lib/frap/generators/templates/dart/src/blocs/base_block.dart.erb
118
119
  - lib/frap/generators/templates/dart/src/config/router.dart.erb
120
+ - lib/frap/generators/templates/dart/src/constants/app_constants.dart.erb
119
121
  - lib/frap/generators/templates/dart/src/constants/pages_list.dart.erb
120
122
  - lib/frap/generators/templates/dart/src/constants/routing.dart.erb
123
+ - lib/frap/generators/templates/dart/src/models/base_model.dart.erb
124
+ - lib/frap/generators/templates/dart/src/resources/base_api_provider.dart.erb
125
+ - lib/frap/generators/templates/dart/src/resources/repository.dart.erb
121
126
  - lib/frap/generators/templates/dart/src/screens/base.dart.erb
127
+ - lib/frap/generators/templates/dart/src/screens/base_bottom_navigation.dart.erb
128
+ - lib/frap/generators/templates/dart/src/screens/base_index.dart.erb
129
+ - lib/frap/generators/templates/dart/src/screens/edit_class.dart.erb
130
+ - lib/frap/generators/templates/dart/src/screens/index_class.dart.erb
131
+ - lib/frap/generators/templates/dart/src/screens/show_class.dart.erb
122
132
  - lib/frap/generators/templates/dart/src/screens/undefined_route_screen.dart.erb
123
133
  - lib/frap/generators/templates/dart/src/widgets/base_app_bar.dart.erb
124
134
  - lib/frap/generators/templates/dart/src/widgets/popup_menu_widget.dart.erb