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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +24 -0
- data/lib/frap.rb +1 -0
- data/lib/frap/create_resource.rb +8 -7
- data/lib/frap/generators/flutter_config.rb +7 -3
- data/lib/frap/generators/flutter_resource.rb +117 -17
- data/lib/frap/generators/templates/dart/src/app.dart.erb +1 -2
- data/lib/frap/generators/templates/dart/src/blocs/base_block.dart.erb +21 -0
- data/lib/frap/generators/templates/dart/src/config/router.dart.erb +0 -1
- data/lib/frap/generators/templates/dart/src/constants/app_constants.dart.erb +1 -0
- data/lib/frap/generators/templates/dart/src/models/base_model.dart.erb +32 -0
- data/lib/frap/generators/templates/dart/src/resources/base_api_provider.dart.erb +18 -0
- data/lib/frap/generators/templates/dart/src/resources/repository.dart.erb +4 -0
- data/lib/frap/generators/templates/dart/src/screens/base.dart.erb +0 -1
- data/lib/frap/generators/templates/dart/src/screens/base_bottom_navigation.dart.erb +57 -0
- data/lib/frap/generators/templates/dart/src/screens/base_index.dart.erb +72 -0
- data/lib/frap/generators/templates/dart/src/screens/edit_class.dart.erb +0 -0
- data/lib/frap/generators/templates/dart/src/screens/index_class.dart.erb +0 -0
- data/lib/frap/generators/templates/dart/src/screens/show_class.dart.erb +0 -0
- data/lib/frap/generators/templates/dart/src/widgets/popup_menu_widget.dart.erb +1 -3
- data/lib/frap/version.rb +1 -1
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2113fe87e979c5dcc6f1068901f9addbb33398ef7bbc54d138d87c37b3813145
|
4
|
+
data.tar.gz: 75f07d7ef133da72c45d1086b28e3054020a6aadeb889a5dc06ad90a2598a9f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2199c30717694e927e1275b0c4c661302b7e1e6f04db69ba06b05f4cee4486aaf440340f0ad7aa85b96a364944d9f193c63dc23fd3f6d350c482f2fd5bb77e92
|
7
|
+
data.tar.gz: 93bdd37d1101b04848a6bdcd86cf69c89c2806548c53f2c54c07f0546d2b5374cc798dab578ecb267741e3021da42eeda80570f5ddfdb7210939fda28623e72d
|
data/Gemfile.lock
CHANGED
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
|
data/lib/frap.rb
CHANGED
data/lib/frap/create_resource.rb
CHANGED
@@ -17,15 +17,16 @@ module Frap
|
|
17
17
|
private
|
18
18
|
|
19
19
|
def generate_rails_resource
|
20
|
-
Dir.chdir("#{working_dir}/#{
|
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
|
-
|
27
|
-
|
28
|
-
|
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
|
55
|
+
def flutter_app_dir
|
55
56
|
config['flutter_app']
|
56
57
|
end
|
57
58
|
|
58
|
-
def
|
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 :
|
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/
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
template('src/
|
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}/#{
|
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
|
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
|
-
|
52
|
-
|
53
|
-
|
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();
|
@@ -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,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
|
+
|
File without changes
|
File without changes
|
File without changes
|
@@ -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,
|
data/lib/frap/version.rb
CHANGED
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.
|
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
|
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
|