adding packages
This commit is contained in:
@@ -0,0 +1,185 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:recase/recase.dart';
|
||||
|
||||
import 'project/project.dart';
|
||||
import 'project/theme.dart';
|
||||
|
||||
const kMetaFileName = 'flutter_editor.json';
|
||||
const kThemeFile = 'lib/ui/theme.dart';
|
||||
|
||||
const String statelessWidgetData = """
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class {{className}} extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
{{#hasChild}}
|
||||
return {{childWidget}}
|
||||
{{/hasChild}}
|
||||
{{^hasChild}}
|
||||
return Container();
|
||||
{{/hasChild}}
|
||||
}
|
||||
}
|
||||
""";
|
||||
const String statefulWidgetData = """
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class {{className}} extends StatefulWidget {
|
||||
@override
|
||||
_{{className}}State createState() => _{{className}}State();
|
||||
}
|
||||
|
||||
class _{{className}}State extends State<{{className}}> {
|
||||
@override
|
||||
{{className}} build(BuildContext context) {
|
||||
return Container(
|
||||
{{#hasChild}}
|
||||
return {{childWidget}}
|
||||
{{/hasChild}}
|
||||
{{^hasChild}}
|
||||
return Container();
|
||||
{{/hasChild}}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
""";
|
||||
|
||||
const String counterExample = """
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class {{className}} extends StatefulWidget {
|
||||
@override
|
||||
_{{className}}State createState() => _{{className}}State();
|
||||
}
|
||||
|
||||
class _{{className}}State extends State<{{className}}> {
|
||||
int _count = 0;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text("Home Screen")),
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'You have pushed the button this many times:',
|
||||
),
|
||||
Text(
|
||||
'\$_count',
|
||||
style: Theme.of(context).textTheme.display1,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
child: Icon(Icons.add),
|
||||
tooltip: "Increment Counter",
|
||||
onPressed: () {
|
||||
if (mounted)
|
||||
setState(() {
|
||||
_count++;
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
""";
|
||||
const String kDefaultAppWidget = """
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
void main() {
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'Flutter Web IDE',
|
||||
themeMode: ThemeMode.{{themeMode}},
|
||||
theme: ThemeData.light(),
|
||||
darkTheme: ThemeData.dark(),
|
||||
home: {{className}}(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
{{childWidget}}
|
||||
|
||||
""";
|
||||
|
||||
String buildCustomColors(List<CustomColor> colors) {
|
||||
if (colors != null) {
|
||||
final sb = StringBuffer();
|
||||
for (var color in colors) {
|
||||
String _name = ReCase(color.name).camelCase;
|
||||
int _value = color.color;
|
||||
sb.writeln(' static Color get $_name => const Color($_value);');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
// TODO: fontFamily: '${options?.fontFamily}',
|
||||
String buildThemeData(FlutterProject project) {
|
||||
final sb = StringBuffer();
|
||||
sb.writeln("""
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
bool isDark(BuildContext context) => Theme.of(context).brightness == Brightness.dark;
|
||||
|
||||
ThemeMode get themeMode => ${(project?.themeMode ?? ThemeMode.system).toString()};
|
||||
|
||||
""");
|
||||
|
||||
sb.writeln(_writeProjectTheme(project?.lightTheme, 'LightTheme', true));
|
||||
sb.writeln(_writeProjectTheme(project?.darkTheme, 'DarkTheme', false));
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
String _writeProjectTheme(ProjectTheme theme, String name, bool isLight) {
|
||||
if (theme == null) {
|
||||
return """
|
||||
class $name {
|
||||
$name._();
|
||||
|
||||
static ThemeData get data => ThemeData.${isLight ? 'light' : 'dark'}();
|
||||
|
||||
}
|
||||
""";
|
||||
}
|
||||
ThemeData _base = isLight ? ThemeData.light() : ThemeData.dark();
|
||||
return """
|
||||
class $name {
|
||||
$name._();
|
||||
|
||||
static ThemeData get data => ThemeData(
|
||||
brightness: ${theme?.lightBrightness ?? isLight ? 'Brightness.light' : 'Brightness.dark'},
|
||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||
textTheme: ThemeData.${isLight ? 'light' : 'dark'}().textTheme
|
||||
).copyWith(
|
||||
primaryColor: const Color(${_getColor(theme?.primaryColor, _base.primaryColor)}),
|
||||
accentColor: const Color(${_getColor(theme?.accentColor, _base.accentColor)}),
|
||||
floatingActionButtonTheme:
|
||||
ThemeData.${isLight ? 'light' : 'dark'}().floatingActionButtonTheme.copyWith(
|
||||
backgroundColor: const Color(${_getColor(theme?.floatingActionButtonBackgroundColor, _base.floatingActionButtonTheme.backgroundColor)}),
|
||||
foregroundColor: const Color(${_getColor(theme?.floatingActionButtonForegroundColor, _base.floatingActionButtonTheme.foregroundColor)}),
|
||||
),
|
||||
scaffoldBackgroundColor: const Color(${_getColor(theme?.scaffoldBackgroundColor, _base.scaffoldBackgroundColor)}),
|
||||
appBarTheme: ThemeData.${isLight ? 'light' : 'dark'}().appBarTheme,
|
||||
);
|
||||
|
||||
${buildCustomColors(theme?.customColors)}
|
||||
}
|
||||
""";
|
||||
}
|
||||
|
||||
int _getColor(int value, Color fallback) {
|
||||
return value ?? fallback?.value ?? Colors.blue.value;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export 'unsupported.dart' if (dart.library.io) 'mobile.dart';
|
||||
@@ -0,0 +1,139 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import '../constants.dart';
|
||||
import '../project/project.dart';
|
||||
import '../project_files.dart';
|
||||
|
||||
Future<ProjectBase> importProject(String path, [String name]) async {
|
||||
print('Project path: $path, $name');
|
||||
final _projectDir = Directory(path);
|
||||
if (_projectDir.existsSync()) {
|
||||
final _files = _projectDir.listSync(followLinks: false);
|
||||
final _projectBase = ProjectBase();
|
||||
_projectBase.meta = FlutterProject(
|
||||
name: name,
|
||||
path: path,
|
||||
);
|
||||
_projectBase.files = [];
|
||||
for (var file in _files) {
|
||||
_projectBase.files.addAll(_readDir(file));
|
||||
}
|
||||
return _projectBase;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
List<ProjectFileBase> _readDir(FileSystemEntity file) {
|
||||
List<ProjectFileBase> _children = [];
|
||||
if (file.path.contains('.symlinks') ||
|
||||
file.path.contains('node_modules') ||
|
||||
file.path.contains('Pods') ||
|
||||
file.path.contains('build') ||
|
||||
file.path.split('/').last.startsWith('.')) {
|
||||
return _children;
|
||||
}
|
||||
debugPrint('$file');
|
||||
if (file is File) {
|
||||
final _file = ProjectFile(file.path, file.readAsBytes());
|
||||
_children.add(_file);
|
||||
}
|
||||
if (file is Directory) {
|
||||
List<ProjectFileBase> _subChildren = [];
|
||||
|
||||
for (var item in file.listSync()) {
|
||||
_subChildren.addAll(_readDir(item));
|
||||
}
|
||||
_children.add(ProjectDirectory(file.path, _subChildren));
|
||||
}
|
||||
return _children;
|
||||
}
|
||||
|
||||
Future<ProjectFileBase> updateLocalFile(String path, List<int> bytes) async {
|
||||
try {
|
||||
final _file = File(path);
|
||||
await _file.create(recursive: true);
|
||||
await _file.writeAsBytes(bytes);
|
||||
} catch (e) {
|
||||
print('Could not update file: $e');
|
||||
}
|
||||
return _fileRaw(path, bytes);
|
||||
}
|
||||
|
||||
Future<List<int>> refreshLocalFile(String path) async {
|
||||
final _file = File(path);
|
||||
return _file.readAsBytes();
|
||||
}
|
||||
|
||||
Future exportToPath(String path, ProjectBase base) async {
|
||||
path ??= '';
|
||||
final _dir = Directory(path);
|
||||
_dir.createSync(recursive: true);
|
||||
|
||||
final _themePath = p.join(path, kThemeFile);
|
||||
final _metaPath = p.join(path, kMetaFileName);
|
||||
final _themeFile = await _file(
|
||||
_themePath,
|
||||
buildThemeData(base.meta),
|
||||
);
|
||||
final _metaFile = await _file(
|
||||
_metaPath,
|
||||
json.encode(base.meta.toJson()),
|
||||
);
|
||||
base.files.removeWhere((element) => element.path == _themePath);
|
||||
base.files.removeWhere((element) => element.path == _metaPath);
|
||||
base.files.addAll([_themeFile, _metaFile]);
|
||||
List<ProjectFileBase> _files = base.files;
|
||||
await _writeFilesDir(_files, path, base);
|
||||
}
|
||||
|
||||
Future _writeFilesDir(
|
||||
List<ProjectFileBase> _files, String path, ProjectBase base) async {
|
||||
for (final file in _files) {
|
||||
if (file is ProjectFile) {
|
||||
await _writeFile(_getNewPath(path, file.path, base.meta.name), file);
|
||||
}
|
||||
if (file is ProjectDirectory) {
|
||||
final _dir = Directory(_getNewPath(path, file.path, base.meta.name));
|
||||
if (!_dir.existsSync()) {
|
||||
_dir.createSync(recursive: true);
|
||||
}
|
||||
if (file?.children != null) {
|
||||
await _writeFilesDir(file.children, path, base);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future _writeFile(String _newPath, ProjectFile file) async {
|
||||
final _file = File(_newPath);
|
||||
if (!_file.existsSync()) {
|
||||
_file.createSync(recursive: true);
|
||||
}
|
||||
final _data = await file.bytes;
|
||||
await _file.writeAsBytesSync(_data);
|
||||
}
|
||||
|
||||
String _getNewPath(String path, String file, String name) {
|
||||
if (file.startsWith(name)) {
|
||||
return p.join(path, file);
|
||||
}
|
||||
final _folderPath = file.split('/$name/').last;
|
||||
final _newPath = p.join(path, _folderPath);
|
||||
return _newPath;
|
||||
}
|
||||
|
||||
Future<ProjectFile> _file(String path, String data) async {
|
||||
final _file = ProjectFile(path, Future.value(utf8.encode(data)));
|
||||
await _file.init();
|
||||
return _file;
|
||||
}
|
||||
|
||||
Future<ProjectFile> _fileRaw(String path, List<int> data) async {
|
||||
final _file = ProjectFile(path, Future.value(data));
|
||||
await _file.init();
|
||||
return _file;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import '../project_files.dart';
|
||||
|
||||
Future<ProjectBase> importProject(String path, [String name]) async {
|
||||
throw 'Platform Not Supported';
|
||||
}
|
||||
|
||||
Future<ProjectFileBase> updateLocalFile(String path, List<int> bytes) async {
|
||||
return _fileRaw(path, bytes);
|
||||
}
|
||||
|
||||
Future<List<int>> refreshLocalFile(String path) async {
|
||||
// throw 'Platform Not Supported';
|
||||
}
|
||||
|
||||
Future exportToPath(String path, ProjectBase base) async {
|
||||
// throw 'Platform Not Supported';
|
||||
}
|
||||
|
||||
Future<ProjectFile> _fileRaw(String path, List<int> data) async {
|
||||
final _file = ProjectFile(path, Future.value(data));
|
||||
await _file.init();
|
||||
return _file;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
import 'theme.dart';
|
||||
import 'widget.dart';
|
||||
|
||||
export 'theme.dart';
|
||||
export 'widget.dart';
|
||||
|
||||
part 'project.freezed.dart';
|
||||
part 'project.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class FlutterProject with _$FlutterProject {
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
factory FlutterProject({
|
||||
@Default('example') String name,
|
||||
@Default('com.example') String org,
|
||||
@Default('A new Flutter project.') String description,
|
||||
@Default(true) bool useSwift,
|
||||
@Default(true) bool useKotlin,
|
||||
@Default(['web']) List<String> targets,
|
||||
String path,
|
||||
String initialRoute,
|
||||
ProjectScreen home,
|
||||
List<ProjectWidget> widgets,
|
||||
ProjectTheme lightTheme,
|
||||
ProjectTheme darkTheme,
|
||||
ThemeMode themeMode,
|
||||
@Default(0) double canvasZoom,
|
||||
@Default(0) double canvasOffsetDx,
|
||||
@Default(0) double canvasOffsetDy,
|
||||
}) = _FlutterProject;
|
||||
|
||||
factory FlutterProject.fromJson(Map<String, dynamic> json) =>
|
||||
_$FlutterProjectFromJson(json);
|
||||
}
|
||||
|
||||
enum ProjectTarget {
|
||||
web,
|
||||
ios,
|
||||
android,
|
||||
windows,
|
||||
linux,
|
||||
macos,
|
||||
}
|
||||
@@ -0,0 +1,521 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named
|
||||
|
||||
part of 'project.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
FlutterProject _$FlutterProjectFromJson(Map<String, dynamic> json) {
|
||||
return _FlutterProject.fromJson(json);
|
||||
}
|
||||
|
||||
class _$FlutterProjectTearOff {
|
||||
const _$FlutterProjectTearOff();
|
||||
|
||||
_FlutterProject call(
|
||||
{String name = 'example',
|
||||
String org = 'com.example',
|
||||
String description = 'A new Flutter project.',
|
||||
bool useSwift = true,
|
||||
bool useKotlin = true,
|
||||
List<String> targets = const ['web'],
|
||||
String path,
|
||||
String initialRoute,
|
||||
ProjectScreen home,
|
||||
List<ProjectWidget> widgets,
|
||||
ProjectTheme lightTheme,
|
||||
ProjectTheme darkTheme,
|
||||
ThemeMode themeMode,
|
||||
double canvasZoom = 0,
|
||||
double canvasOffsetDx = 0,
|
||||
double canvasOffsetDy = 0}) {
|
||||
return _FlutterProject(
|
||||
name: name,
|
||||
org: org,
|
||||
description: description,
|
||||
useSwift: useSwift,
|
||||
useKotlin: useKotlin,
|
||||
targets: targets,
|
||||
path: path,
|
||||
initialRoute: initialRoute,
|
||||
home: home,
|
||||
widgets: widgets,
|
||||
lightTheme: lightTheme,
|
||||
darkTheme: darkTheme,
|
||||
themeMode: themeMode,
|
||||
canvasZoom: canvasZoom,
|
||||
canvasOffsetDx: canvasOffsetDx,
|
||||
canvasOffsetDy: canvasOffsetDy,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
const $FlutterProject = _$FlutterProjectTearOff();
|
||||
|
||||
mixin _$FlutterProject {
|
||||
String get name;
|
||||
String get org;
|
||||
String get description;
|
||||
bool get useSwift;
|
||||
bool get useKotlin;
|
||||
List<String> get targets;
|
||||
String get path;
|
||||
String get initialRoute;
|
||||
ProjectScreen get home;
|
||||
List<ProjectWidget> get widgets;
|
||||
ProjectTheme get lightTheme;
|
||||
ProjectTheme get darkTheme;
|
||||
ThemeMode get themeMode;
|
||||
double get canvasZoom;
|
||||
double get canvasOffsetDx;
|
||||
double get canvasOffsetDy;
|
||||
|
||||
Map<String, dynamic> toJson();
|
||||
$FlutterProjectCopyWith<FlutterProject> get copyWith;
|
||||
}
|
||||
|
||||
abstract class $FlutterProjectCopyWith<$Res> {
|
||||
factory $FlutterProjectCopyWith(
|
||||
FlutterProject value, $Res Function(FlutterProject) then) =
|
||||
_$FlutterProjectCopyWithImpl<$Res>;
|
||||
$Res call(
|
||||
{String name,
|
||||
String org,
|
||||
String description,
|
||||
bool useSwift,
|
||||
bool useKotlin,
|
||||
List<String> targets,
|
||||
String path,
|
||||
String initialRoute,
|
||||
ProjectScreen home,
|
||||
List<ProjectWidget> widgets,
|
||||
ProjectTheme lightTheme,
|
||||
ProjectTheme darkTheme,
|
||||
ThemeMode themeMode,
|
||||
double canvasZoom,
|
||||
double canvasOffsetDx,
|
||||
double canvasOffsetDy});
|
||||
|
||||
$ProjectThemeCopyWith<$Res> get lightTheme;
|
||||
$ProjectThemeCopyWith<$Res> get darkTheme;
|
||||
}
|
||||
|
||||
class _$FlutterProjectCopyWithImpl<$Res>
|
||||
implements $FlutterProjectCopyWith<$Res> {
|
||||
_$FlutterProjectCopyWithImpl(this._value, this._then);
|
||||
|
||||
final FlutterProject _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function(FlutterProject) _then;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object name = freezed,
|
||||
Object org = freezed,
|
||||
Object description = freezed,
|
||||
Object useSwift = freezed,
|
||||
Object useKotlin = freezed,
|
||||
Object targets = freezed,
|
||||
Object path = freezed,
|
||||
Object initialRoute = freezed,
|
||||
Object home = freezed,
|
||||
Object widgets = freezed,
|
||||
Object lightTheme = freezed,
|
||||
Object darkTheme = freezed,
|
||||
Object themeMode = freezed,
|
||||
Object canvasZoom = freezed,
|
||||
Object canvasOffsetDx = freezed,
|
||||
Object canvasOffsetDy = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
name: name == freezed ? _value.name : name as String,
|
||||
org: org == freezed ? _value.org : org as String,
|
||||
description:
|
||||
description == freezed ? _value.description : description as String,
|
||||
useSwift: useSwift == freezed ? _value.useSwift : useSwift as bool,
|
||||
useKotlin: useKotlin == freezed ? _value.useKotlin : useKotlin as bool,
|
||||
targets: targets == freezed ? _value.targets : targets as List<String>,
|
||||
path: path == freezed ? _value.path : path as String,
|
||||
initialRoute: initialRoute == freezed
|
||||
? _value.initialRoute
|
||||
: initialRoute as String,
|
||||
home: home == freezed ? _value.home : home as ProjectScreen,
|
||||
widgets:
|
||||
widgets == freezed ? _value.widgets : widgets as List<ProjectWidget>,
|
||||
lightTheme: lightTheme == freezed
|
||||
? _value.lightTheme
|
||||
: lightTheme as ProjectTheme,
|
||||
darkTheme:
|
||||
darkTheme == freezed ? _value.darkTheme : darkTheme as ProjectTheme,
|
||||
themeMode:
|
||||
themeMode == freezed ? _value.themeMode : themeMode as ThemeMode,
|
||||
canvasZoom:
|
||||
canvasZoom == freezed ? _value.canvasZoom : canvasZoom as double,
|
||||
canvasOffsetDx: canvasOffsetDx == freezed
|
||||
? _value.canvasOffsetDx
|
||||
: canvasOffsetDx as double,
|
||||
canvasOffsetDy: canvasOffsetDy == freezed
|
||||
? _value.canvasOffsetDy
|
||||
: canvasOffsetDy as double,
|
||||
));
|
||||
}
|
||||
|
||||
@override
|
||||
$ProjectThemeCopyWith<$Res> get lightTheme {
|
||||
if (_value.lightTheme == null) {
|
||||
return null;
|
||||
}
|
||||
return $ProjectThemeCopyWith<$Res>(_value.lightTheme, (value) {
|
||||
return _then(_value.copyWith(lightTheme: value));
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
$ProjectThemeCopyWith<$Res> get darkTheme {
|
||||
if (_value.darkTheme == null) {
|
||||
return null;
|
||||
}
|
||||
return $ProjectThemeCopyWith<$Res>(_value.darkTheme, (value) {
|
||||
return _then(_value.copyWith(darkTheme: value));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _$FlutterProjectCopyWith<$Res>
|
||||
implements $FlutterProjectCopyWith<$Res> {
|
||||
factory _$FlutterProjectCopyWith(
|
||||
_FlutterProject value, $Res Function(_FlutterProject) then) =
|
||||
__$FlutterProjectCopyWithImpl<$Res>;
|
||||
@override
|
||||
$Res call(
|
||||
{String name,
|
||||
String org,
|
||||
String description,
|
||||
bool useSwift,
|
||||
bool useKotlin,
|
||||
List<String> targets,
|
||||
String path,
|
||||
String initialRoute,
|
||||
ProjectScreen home,
|
||||
List<ProjectWidget> widgets,
|
||||
ProjectTheme lightTheme,
|
||||
ProjectTheme darkTheme,
|
||||
ThemeMode themeMode,
|
||||
double canvasZoom,
|
||||
double canvasOffsetDx,
|
||||
double canvasOffsetDy});
|
||||
|
||||
@override
|
||||
$ProjectThemeCopyWith<$Res> get lightTheme;
|
||||
@override
|
||||
$ProjectThemeCopyWith<$Res> get darkTheme;
|
||||
}
|
||||
|
||||
class __$FlutterProjectCopyWithImpl<$Res>
|
||||
extends _$FlutterProjectCopyWithImpl<$Res>
|
||||
implements _$FlutterProjectCopyWith<$Res> {
|
||||
__$FlutterProjectCopyWithImpl(
|
||||
_FlutterProject _value, $Res Function(_FlutterProject) _then)
|
||||
: super(_value, (v) => _then(v as _FlutterProject));
|
||||
|
||||
@override
|
||||
_FlutterProject get _value => super._value as _FlutterProject;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object name = freezed,
|
||||
Object org = freezed,
|
||||
Object description = freezed,
|
||||
Object useSwift = freezed,
|
||||
Object useKotlin = freezed,
|
||||
Object targets = freezed,
|
||||
Object path = freezed,
|
||||
Object initialRoute = freezed,
|
||||
Object home = freezed,
|
||||
Object widgets = freezed,
|
||||
Object lightTheme = freezed,
|
||||
Object darkTheme = freezed,
|
||||
Object themeMode = freezed,
|
||||
Object canvasZoom = freezed,
|
||||
Object canvasOffsetDx = freezed,
|
||||
Object canvasOffsetDy = freezed,
|
||||
}) {
|
||||
return _then(_FlutterProject(
|
||||
name: name == freezed ? _value.name : name as String,
|
||||
org: org == freezed ? _value.org : org as String,
|
||||
description:
|
||||
description == freezed ? _value.description : description as String,
|
||||
useSwift: useSwift == freezed ? _value.useSwift : useSwift as bool,
|
||||
useKotlin: useKotlin == freezed ? _value.useKotlin : useKotlin as bool,
|
||||
targets: targets == freezed ? _value.targets : targets as List<String>,
|
||||
path: path == freezed ? _value.path : path as String,
|
||||
initialRoute: initialRoute == freezed
|
||||
? _value.initialRoute
|
||||
: initialRoute as String,
|
||||
home: home == freezed ? _value.home : home as ProjectScreen,
|
||||
widgets:
|
||||
widgets == freezed ? _value.widgets : widgets as List<ProjectWidget>,
|
||||
lightTheme: lightTheme == freezed
|
||||
? _value.lightTheme
|
||||
: lightTheme as ProjectTheme,
|
||||
darkTheme:
|
||||
darkTheme == freezed ? _value.darkTheme : darkTheme as ProjectTheme,
|
||||
themeMode:
|
||||
themeMode == freezed ? _value.themeMode : themeMode as ThemeMode,
|
||||
canvasZoom:
|
||||
canvasZoom == freezed ? _value.canvasZoom : canvasZoom as double,
|
||||
canvasOffsetDx: canvasOffsetDx == freezed
|
||||
? _value.canvasOffsetDx
|
||||
: canvasOffsetDx as double,
|
||||
canvasOffsetDy: canvasOffsetDy == freezed
|
||||
? _value.canvasOffsetDy
|
||||
: canvasOffsetDy as double,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class _$_FlutterProject
|
||||
with DiagnosticableTreeMixin
|
||||
implements _FlutterProject {
|
||||
_$_FlutterProject(
|
||||
{this.name = 'example',
|
||||
this.org = 'com.example',
|
||||
this.description = 'A new Flutter project.',
|
||||
this.useSwift = true,
|
||||
this.useKotlin = true,
|
||||
this.targets = const ['web'],
|
||||
this.path,
|
||||
this.initialRoute,
|
||||
this.home,
|
||||
this.widgets,
|
||||
this.lightTheme,
|
||||
this.darkTheme,
|
||||
this.themeMode,
|
||||
this.canvasZoom = 0,
|
||||
this.canvasOffsetDx = 0,
|
||||
this.canvasOffsetDy = 0})
|
||||
: assert(name != null),
|
||||
assert(org != null),
|
||||
assert(description != null),
|
||||
assert(useSwift != null),
|
||||
assert(useKotlin != null),
|
||||
assert(targets != null),
|
||||
assert(canvasZoom != null),
|
||||
assert(canvasOffsetDx != null),
|
||||
assert(canvasOffsetDy != null);
|
||||
|
||||
factory _$_FlutterProject.fromJson(Map<String, dynamic> json) =>
|
||||
_$_$_FlutterProjectFromJson(json);
|
||||
|
||||
@JsonKey(defaultValue: 'example')
|
||||
@override
|
||||
final String name;
|
||||
@JsonKey(defaultValue: 'com.example')
|
||||
@override
|
||||
final String org;
|
||||
@JsonKey(defaultValue: 'A new Flutter project.')
|
||||
@override
|
||||
final String description;
|
||||
@JsonKey(defaultValue: true)
|
||||
@override
|
||||
final bool useSwift;
|
||||
@JsonKey(defaultValue: true)
|
||||
@override
|
||||
final bool useKotlin;
|
||||
@JsonKey(defaultValue: const ['web'])
|
||||
@override
|
||||
final List<String> targets;
|
||||
@override
|
||||
final String path;
|
||||
@override
|
||||
final String initialRoute;
|
||||
@override
|
||||
final ProjectScreen home;
|
||||
@override
|
||||
final List<ProjectWidget> widgets;
|
||||
@override
|
||||
final ProjectTheme lightTheme;
|
||||
@override
|
||||
final ProjectTheme darkTheme;
|
||||
@override
|
||||
final ThemeMode themeMode;
|
||||
@JsonKey(defaultValue: 0)
|
||||
@override
|
||||
final double canvasZoom;
|
||||
@JsonKey(defaultValue: 0)
|
||||
@override
|
||||
final double canvasOffsetDx;
|
||||
@JsonKey(defaultValue: 0)
|
||||
@override
|
||||
final double canvasOffsetDy;
|
||||
|
||||
@override
|
||||
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
|
||||
return 'FlutterProject(name: $name, org: $org, description: $description, useSwift: $useSwift, useKotlin: $useKotlin, targets: $targets, path: $path, initialRoute: $initialRoute, home: $home, widgets: $widgets, lightTheme: $lightTheme, darkTheme: $darkTheme, themeMode: $themeMode, canvasZoom: $canvasZoom, canvasOffsetDx: $canvasOffsetDx, canvasOffsetDy: $canvasOffsetDy)';
|
||||
}
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties
|
||||
..add(DiagnosticsProperty('type', 'FlutterProject'))
|
||||
..add(DiagnosticsProperty('name', name))
|
||||
..add(DiagnosticsProperty('org', org))
|
||||
..add(DiagnosticsProperty('description', description))
|
||||
..add(DiagnosticsProperty('useSwift', useSwift))
|
||||
..add(DiagnosticsProperty('useKotlin', useKotlin))
|
||||
..add(DiagnosticsProperty('targets', targets))
|
||||
..add(DiagnosticsProperty('path', path))
|
||||
..add(DiagnosticsProperty('initialRoute', initialRoute))
|
||||
..add(DiagnosticsProperty('home', home))
|
||||
..add(DiagnosticsProperty('widgets', widgets))
|
||||
..add(DiagnosticsProperty('lightTheme', lightTheme))
|
||||
..add(DiagnosticsProperty('darkTheme', darkTheme))
|
||||
..add(DiagnosticsProperty('themeMode', themeMode))
|
||||
..add(DiagnosticsProperty('canvasZoom', canvasZoom))
|
||||
..add(DiagnosticsProperty('canvasOffsetDx', canvasOffsetDx))
|
||||
..add(DiagnosticsProperty('canvasOffsetDy', canvasOffsetDy));
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) ||
|
||||
(other is _FlutterProject &&
|
||||
(identical(other.name, name) ||
|
||||
const DeepCollectionEquality().equals(other.name, name)) &&
|
||||
(identical(other.org, org) ||
|
||||
const DeepCollectionEquality().equals(other.org, org)) &&
|
||||
(identical(other.description, description) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.description, description)) &&
|
||||
(identical(other.useSwift, useSwift) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.useSwift, useSwift)) &&
|
||||
(identical(other.useKotlin, useKotlin) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.useKotlin, useKotlin)) &&
|
||||
(identical(other.targets, targets) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.targets, targets)) &&
|
||||
(identical(other.path, path) ||
|
||||
const DeepCollectionEquality().equals(other.path, path)) &&
|
||||
(identical(other.initialRoute, initialRoute) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.initialRoute, initialRoute)) &&
|
||||
(identical(other.home, home) ||
|
||||
const DeepCollectionEquality().equals(other.home, home)) &&
|
||||
(identical(other.widgets, widgets) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.widgets, widgets)) &&
|
||||
(identical(other.lightTheme, lightTheme) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.lightTheme, lightTheme)) &&
|
||||
(identical(other.darkTheme, darkTheme) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.darkTheme, darkTheme)) &&
|
||||
(identical(other.themeMode, themeMode) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.themeMode, themeMode)) &&
|
||||
(identical(other.canvasZoom, canvasZoom) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.canvasZoom, canvasZoom)) &&
|
||||
(identical(other.canvasOffsetDx, canvasOffsetDx) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.canvasOffsetDx, canvasOffsetDx)) &&
|
||||
(identical(other.canvasOffsetDy, canvasOffsetDy) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.canvasOffsetDy, canvasOffsetDy)));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
runtimeType.hashCode ^
|
||||
const DeepCollectionEquality().hash(name) ^
|
||||
const DeepCollectionEquality().hash(org) ^
|
||||
const DeepCollectionEquality().hash(description) ^
|
||||
const DeepCollectionEquality().hash(useSwift) ^
|
||||
const DeepCollectionEquality().hash(useKotlin) ^
|
||||
const DeepCollectionEquality().hash(targets) ^
|
||||
const DeepCollectionEquality().hash(path) ^
|
||||
const DeepCollectionEquality().hash(initialRoute) ^
|
||||
const DeepCollectionEquality().hash(home) ^
|
||||
const DeepCollectionEquality().hash(widgets) ^
|
||||
const DeepCollectionEquality().hash(lightTheme) ^
|
||||
const DeepCollectionEquality().hash(darkTheme) ^
|
||||
const DeepCollectionEquality().hash(themeMode) ^
|
||||
const DeepCollectionEquality().hash(canvasZoom) ^
|
||||
const DeepCollectionEquality().hash(canvasOffsetDx) ^
|
||||
const DeepCollectionEquality().hash(canvasOffsetDy);
|
||||
|
||||
@override
|
||||
_$FlutterProjectCopyWith<_FlutterProject> get copyWith =>
|
||||
__$FlutterProjectCopyWithImpl<_FlutterProject>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$_$_FlutterProjectToJson(this);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _FlutterProject implements FlutterProject {
|
||||
factory _FlutterProject(
|
||||
{String name,
|
||||
String org,
|
||||
String description,
|
||||
bool useSwift,
|
||||
bool useKotlin,
|
||||
List<String> targets,
|
||||
String path,
|
||||
String initialRoute,
|
||||
ProjectScreen home,
|
||||
List<ProjectWidget> widgets,
|
||||
ProjectTheme lightTheme,
|
||||
ProjectTheme darkTheme,
|
||||
ThemeMode themeMode,
|
||||
double canvasZoom,
|
||||
double canvasOffsetDx,
|
||||
double canvasOffsetDy}) = _$_FlutterProject;
|
||||
|
||||
factory _FlutterProject.fromJson(Map<String, dynamic> json) =
|
||||
_$_FlutterProject.fromJson;
|
||||
|
||||
@override
|
||||
String get name;
|
||||
@override
|
||||
String get org;
|
||||
@override
|
||||
String get description;
|
||||
@override
|
||||
bool get useSwift;
|
||||
@override
|
||||
bool get useKotlin;
|
||||
@override
|
||||
List<String> get targets;
|
||||
@override
|
||||
String get path;
|
||||
@override
|
||||
String get initialRoute;
|
||||
@override
|
||||
ProjectScreen get home;
|
||||
@override
|
||||
List<ProjectWidget> get widgets;
|
||||
@override
|
||||
ProjectTheme get lightTheme;
|
||||
@override
|
||||
ProjectTheme get darkTheme;
|
||||
@override
|
||||
ThemeMode get themeMode;
|
||||
@override
|
||||
double get canvasZoom;
|
||||
@override
|
||||
double get canvasOffsetDx;
|
||||
@override
|
||||
double get canvasOffsetDy;
|
||||
@override
|
||||
_$FlutterProjectCopyWith<_FlutterProject> get copyWith;
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'project.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$_FlutterProject _$_$_FlutterProjectFromJson(Map<String, dynamic> json) {
|
||||
return _$_FlutterProject(
|
||||
name: json['name'] as String ?? 'example',
|
||||
org: json['org'] as String ?? 'com.example',
|
||||
description: json['description'] as String ?? 'A new Flutter project.',
|
||||
useSwift: json['useSwift'] as bool ?? true,
|
||||
useKotlin: json['useKotlin'] as bool ?? true,
|
||||
targets:
|
||||
(json['targets'] as List)?.map((e) => e as String)?.toList() ?? ['web'],
|
||||
path: json['path'] as String,
|
||||
initialRoute: json['initialRoute'] as String,
|
||||
home: json['home'] == null
|
||||
? null
|
||||
: ProjectScreen.fromJson(json['home'] as Map<String, dynamic>),
|
||||
widgets: (json['widgets'] as List)
|
||||
?.map((e) => e == null
|
||||
? null
|
||||
: ProjectWidget.fromJson(e as Map<String, dynamic>))
|
||||
?.toList(),
|
||||
lightTheme: json['lightTheme'] == null
|
||||
? null
|
||||
: ProjectTheme.fromJson(json['lightTheme'] as Map<String, dynamic>),
|
||||
darkTheme: json['darkTheme'] == null
|
||||
? null
|
||||
: ProjectTheme.fromJson(json['darkTheme'] as Map<String, dynamic>),
|
||||
themeMode: _$enumDecodeNullable(_$ThemeModeEnumMap, json['themeMode']),
|
||||
canvasZoom: (json['canvasZoom'] as num)?.toDouble() ?? 0,
|
||||
canvasOffsetDx: (json['canvasOffsetDx'] as num)?.toDouble() ?? 0,
|
||||
canvasOffsetDy: (json['canvasOffsetDy'] as num)?.toDouble() ?? 0,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$_$_FlutterProjectToJson(_$_FlutterProject instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'org': instance.org,
|
||||
'description': instance.description,
|
||||
'useSwift': instance.useSwift,
|
||||
'useKotlin': instance.useKotlin,
|
||||
'targets': instance.targets,
|
||||
'path': instance.path,
|
||||
'initialRoute': instance.initialRoute,
|
||||
'home': instance.home?.toJson(),
|
||||
'widgets': instance.widgets?.map((e) => e?.toJson())?.toList(),
|
||||
'lightTheme': instance.lightTheme?.toJson(),
|
||||
'darkTheme': instance.darkTheme?.toJson(),
|
||||
'themeMode': _$ThemeModeEnumMap[instance.themeMode],
|
||||
'canvasZoom': instance.canvasZoom,
|
||||
'canvasOffsetDx': instance.canvasOffsetDx,
|
||||
'canvasOffsetDy': instance.canvasOffsetDy,
|
||||
};
|
||||
|
||||
T _$enumDecode<T>(
|
||||
Map<T, dynamic> enumValues,
|
||||
dynamic source, {
|
||||
T unknownValue,
|
||||
}) {
|
||||
if (source == null) {
|
||||
throw ArgumentError('A value must be provided. Supported values: '
|
||||
'${enumValues.values.join(', ')}');
|
||||
}
|
||||
|
||||
final value = enumValues.entries
|
||||
.singleWhere((e) => e.value == source, orElse: () => null)
|
||||
?.key;
|
||||
|
||||
if (value == null && unknownValue == null) {
|
||||
throw ArgumentError('`$source` is not one of the supported values: '
|
||||
'${enumValues.values.join(', ')}');
|
||||
}
|
||||
return value ?? unknownValue;
|
||||
}
|
||||
|
||||
T _$enumDecodeNullable<T>(
|
||||
Map<T, dynamic> enumValues,
|
||||
dynamic source, {
|
||||
T unknownValue,
|
||||
}) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return _$enumDecode<T>(enumValues, source, unknownValue: unknownValue);
|
||||
}
|
||||
|
||||
const _$ThemeModeEnumMap = {
|
||||
ThemeMode.system: 'system',
|
||||
ThemeMode.light: 'light',
|
||||
ThemeMode.dark: 'dark',
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'theme.freezed.dart';
|
||||
part 'theme.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class ProjectTheme with _$ProjectTheme {
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
factory ProjectTheme({
|
||||
bool lightBrightness,
|
||||
int primaryColor,
|
||||
int accentColor,
|
||||
int scaffoldBackgroundColor,
|
||||
int floatingActionButtonBackgroundColor,
|
||||
int floatingActionButtonForegroundColor,
|
||||
List<CustomColor> customColors,
|
||||
List<CustomGradient> customGradients,
|
||||
}) = _ProjectTheme;
|
||||
|
||||
factory ProjectTheme.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProjectThemeFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class CustomColor with _$CustomColor {
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
factory CustomColor({
|
||||
String name,
|
||||
int color,
|
||||
}) = _CustomColor;
|
||||
|
||||
factory CustomColor.fromJson(Map<String, dynamic> json) =>
|
||||
_$CustomColorFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class CustomGradient with _$CustomGradient {
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
factory CustomGradient({
|
||||
String name,
|
||||
List<int> colors,
|
||||
}) = _CustomGradient;
|
||||
|
||||
factory CustomGradient.radial({
|
||||
String name,
|
||||
List<double> stops,
|
||||
List<int> colors,
|
||||
double radius,
|
||||
double alignX,
|
||||
double alignY,
|
||||
double focalX,
|
||||
double focalY,
|
||||
}) = CustomRadialGradient;
|
||||
|
||||
factory CustomGradient.linear({
|
||||
String name,
|
||||
List<double> stops,
|
||||
List<int> colors,
|
||||
double radius,
|
||||
double startX,
|
||||
double startY,
|
||||
double endX,
|
||||
double endY,
|
||||
TileMode tileMode,
|
||||
}) = CustomLinearGradient;
|
||||
|
||||
factory CustomGradient.fromJson(Map<String, dynamic> json) =>
|
||||
_$CustomGradientFromJson(json);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,166 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'theme.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$_ProjectTheme _$_$_ProjectThemeFromJson(Map<String, dynamic> json) {
|
||||
return _$_ProjectTheme(
|
||||
lightBrightness: json['lightBrightness'] as bool,
|
||||
primaryColor: json['primaryColor'] as int,
|
||||
accentColor: json['accentColor'] as int,
|
||||
scaffoldBackgroundColor: json['scaffoldBackgroundColor'] as int,
|
||||
floatingActionButtonBackgroundColor:
|
||||
json['floatingActionButtonBackgroundColor'] as int,
|
||||
floatingActionButtonForegroundColor:
|
||||
json['floatingActionButtonForegroundColor'] as int,
|
||||
customColors: (json['customColors'] as List)
|
||||
?.map((e) =>
|
||||
e == null ? null : CustomColor.fromJson(e as Map<String, dynamic>))
|
||||
?.toList(),
|
||||
customGradients: (json['customGradients'] as List)
|
||||
?.map((e) => e == null
|
||||
? null
|
||||
: CustomGradient.fromJson(e as Map<String, dynamic>))
|
||||
?.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$_$_ProjectThemeToJson(_$_ProjectTheme instance) =>
|
||||
<String, dynamic>{
|
||||
'lightBrightness': instance.lightBrightness,
|
||||
'primaryColor': instance.primaryColor,
|
||||
'accentColor': instance.accentColor,
|
||||
'scaffoldBackgroundColor': instance.scaffoldBackgroundColor,
|
||||
'floatingActionButtonBackgroundColor':
|
||||
instance.floatingActionButtonBackgroundColor,
|
||||
'floatingActionButtonForegroundColor':
|
||||
instance.floatingActionButtonForegroundColor,
|
||||
'customColors': instance.customColors?.map((e) => e?.toJson())?.toList(),
|
||||
'customGradients':
|
||||
instance.customGradients?.map((e) => e?.toJson())?.toList(),
|
||||
};
|
||||
|
||||
_$_CustomColor _$_$_CustomColorFromJson(Map<String, dynamic> json) {
|
||||
return _$_CustomColor(
|
||||
name: json['name'] as String,
|
||||
color: json['color'] as int,
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$_$_CustomColorToJson(_$_CustomColor instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'color': instance.color,
|
||||
};
|
||||
|
||||
_$_CustomGradient _$_$_CustomGradientFromJson(Map<String, dynamic> json) {
|
||||
return _$_CustomGradient(
|
||||
name: json['name'] as String,
|
||||
colors: (json['colors'] as List)?.map((e) => e as int)?.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$_$_CustomGradientToJson(_$_CustomGradient instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'colors': instance.colors,
|
||||
};
|
||||
|
||||
_$CustomRadialGradient _$_$CustomRadialGradientFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return _$CustomRadialGradient(
|
||||
name: json['name'] as String,
|
||||
stops:
|
||||
(json['stops'] as List)?.map((e) => (e as num)?.toDouble())?.toList(),
|
||||
colors: (json['colors'] as List)?.map((e) => e as int)?.toList(),
|
||||
radius: (json['radius'] as num)?.toDouble(),
|
||||
alignX: (json['alignX'] as num)?.toDouble(),
|
||||
alignY: (json['alignY'] as num)?.toDouble(),
|
||||
focalX: (json['focalX'] as num)?.toDouble(),
|
||||
focalY: (json['focalY'] as num)?.toDouble(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$_$CustomRadialGradientToJson(
|
||||
_$CustomRadialGradient instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'stops': instance.stops,
|
||||
'colors': instance.colors,
|
||||
'radius': instance.radius,
|
||||
'alignX': instance.alignX,
|
||||
'alignY': instance.alignY,
|
||||
'focalX': instance.focalX,
|
||||
'focalY': instance.focalY,
|
||||
};
|
||||
|
||||
_$CustomLinearGradient _$_$CustomLinearGradientFromJson(
|
||||
Map<String, dynamic> json) {
|
||||
return _$CustomLinearGradient(
|
||||
name: json['name'] as String,
|
||||
stops:
|
||||
(json['stops'] as List)?.map((e) => (e as num)?.toDouble())?.toList(),
|
||||
colors: (json['colors'] as List)?.map((e) => e as int)?.toList(),
|
||||
radius: (json['radius'] as num)?.toDouble(),
|
||||
startX: (json['startX'] as num)?.toDouble(),
|
||||
startY: (json['startY'] as num)?.toDouble(),
|
||||
endX: (json['endX'] as num)?.toDouble(),
|
||||
endY: (json['endY'] as num)?.toDouble(),
|
||||
tileMode: _$enumDecodeNullable(_$TileModeEnumMap, json['tileMode']),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$_$CustomLinearGradientToJson(
|
||||
_$CustomLinearGradient instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'stops': instance.stops,
|
||||
'colors': instance.colors,
|
||||
'radius': instance.radius,
|
||||
'startX': instance.startX,
|
||||
'startY': instance.startY,
|
||||
'endX': instance.endX,
|
||||
'endY': instance.endY,
|
||||
'tileMode': _$TileModeEnumMap[instance.tileMode],
|
||||
};
|
||||
|
||||
T _$enumDecode<T>(
|
||||
Map<T, dynamic> enumValues,
|
||||
dynamic source, {
|
||||
T unknownValue,
|
||||
}) {
|
||||
if (source == null) {
|
||||
throw ArgumentError('A value must be provided. Supported values: '
|
||||
'${enumValues.values.join(', ')}');
|
||||
}
|
||||
|
||||
final value = enumValues.entries
|
||||
.singleWhere((e) => e.value == source, orElse: () => null)
|
||||
?.key;
|
||||
|
||||
if (value == null && unknownValue == null) {
|
||||
throw ArgumentError('`$source` is not one of the supported values: '
|
||||
'${enumValues.values.join(', ')}');
|
||||
}
|
||||
return value ?? unknownValue;
|
||||
}
|
||||
|
||||
T _$enumDecodeNullable<T>(
|
||||
Map<T, dynamic> enumValues,
|
||||
dynamic source, {
|
||||
T unknownValue,
|
||||
}) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
return _$enumDecode<T>(enumValues, source, unknownValue: unknownValue);
|
||||
}
|
||||
|
||||
const _$TileModeEnumMap = {
|
||||
TileMode.clamp: 'clamp',
|
||||
TileMode.repeated: 'repeated',
|
||||
TileMode.mirror: 'mirror',
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'widget.freezed.dart';
|
||||
part 'widget.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class ProjectWidget with _$ProjectWidget {
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
factory ProjectWidget.screen({
|
||||
String path,
|
||||
@Default('MyScreen') String className,
|
||||
@Default(false) bool isStateful,
|
||||
@Default('/') String route,
|
||||
String data,
|
||||
List<String> tokens,
|
||||
List<String> callbacks,
|
||||
double dx,
|
||||
double dy,
|
||||
double width,
|
||||
double height,
|
||||
}) = ProjectScreen;
|
||||
|
||||
factory ProjectWidget.fromJson(Map<String, dynamic> json) =>
|
||||
_$ProjectWidgetFromJson(json);
|
||||
}
|
||||
@@ -0,0 +1,353 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
// ignore_for_file: deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named
|
||||
|
||||
part of 'widget.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
// **************************************************************************
|
||||
|
||||
T _$identity<T>(T value) => value;
|
||||
ProjectWidget _$ProjectWidgetFromJson(Map<String, dynamic> json) {
|
||||
return ProjectScreen.fromJson(json);
|
||||
}
|
||||
|
||||
class _$ProjectWidgetTearOff {
|
||||
const _$ProjectWidgetTearOff();
|
||||
|
||||
ProjectScreen screen(
|
||||
{String path,
|
||||
String className = 'MyScreen',
|
||||
bool isStateful = false,
|
||||
String route = '/',
|
||||
String data,
|
||||
List<String> tokens,
|
||||
List<String> callbacks,
|
||||
double dx,
|
||||
double dy,
|
||||
double width,
|
||||
double height}) {
|
||||
return ProjectScreen(
|
||||
path: path,
|
||||
className: className,
|
||||
isStateful: isStateful,
|
||||
route: route,
|
||||
data: data,
|
||||
tokens: tokens,
|
||||
callbacks: callbacks,
|
||||
dx: dx,
|
||||
dy: dy,
|
||||
width: width,
|
||||
height: height,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
const $ProjectWidget = _$ProjectWidgetTearOff();
|
||||
|
||||
mixin _$ProjectWidget {
|
||||
String get path;
|
||||
String get className;
|
||||
bool get isStateful;
|
||||
String get route;
|
||||
String get data;
|
||||
List<String> get tokens;
|
||||
List<String> get callbacks;
|
||||
double get dx;
|
||||
double get dy;
|
||||
double get width;
|
||||
double get height;
|
||||
|
||||
Map<String, dynamic> toJson();
|
||||
$ProjectWidgetCopyWith<ProjectWidget> get copyWith;
|
||||
}
|
||||
|
||||
abstract class $ProjectWidgetCopyWith<$Res> {
|
||||
factory $ProjectWidgetCopyWith(
|
||||
ProjectWidget value, $Res Function(ProjectWidget) then) =
|
||||
_$ProjectWidgetCopyWithImpl<$Res>;
|
||||
$Res call(
|
||||
{String path,
|
||||
String className,
|
||||
bool isStateful,
|
||||
String route,
|
||||
String data,
|
||||
List<String> tokens,
|
||||
List<String> callbacks,
|
||||
double dx,
|
||||
double dy,
|
||||
double width,
|
||||
double height});
|
||||
}
|
||||
|
||||
class _$ProjectWidgetCopyWithImpl<$Res>
|
||||
implements $ProjectWidgetCopyWith<$Res> {
|
||||
_$ProjectWidgetCopyWithImpl(this._value, this._then);
|
||||
|
||||
final ProjectWidget _value;
|
||||
// ignore: unused_field
|
||||
final $Res Function(ProjectWidget) _then;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object path = freezed,
|
||||
Object className = freezed,
|
||||
Object isStateful = freezed,
|
||||
Object route = freezed,
|
||||
Object data = freezed,
|
||||
Object tokens = freezed,
|
||||
Object callbacks = freezed,
|
||||
Object dx = freezed,
|
||||
Object dy = freezed,
|
||||
Object width = freezed,
|
||||
Object height = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
path: path == freezed ? _value.path : path as String,
|
||||
className: className == freezed ? _value.className : className as String,
|
||||
isStateful:
|
||||
isStateful == freezed ? _value.isStateful : isStateful as bool,
|
||||
route: route == freezed ? _value.route : route as String,
|
||||
data: data == freezed ? _value.data : data as String,
|
||||
tokens: tokens == freezed ? _value.tokens : tokens as List<String>,
|
||||
callbacks:
|
||||
callbacks == freezed ? _value.callbacks : callbacks as List<String>,
|
||||
dx: dx == freezed ? _value.dx : dx as double,
|
||||
dy: dy == freezed ? _value.dy : dy as double,
|
||||
width: width == freezed ? _value.width : width as double,
|
||||
height: height == freezed ? _value.height : height as double,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class $ProjectScreenCopyWith<$Res>
|
||||
implements $ProjectWidgetCopyWith<$Res> {
|
||||
factory $ProjectScreenCopyWith(
|
||||
ProjectScreen value, $Res Function(ProjectScreen) then) =
|
||||
_$ProjectScreenCopyWithImpl<$Res>;
|
||||
@override
|
||||
$Res call(
|
||||
{String path,
|
||||
String className,
|
||||
bool isStateful,
|
||||
String route,
|
||||
String data,
|
||||
List<String> tokens,
|
||||
List<String> callbacks,
|
||||
double dx,
|
||||
double dy,
|
||||
double width,
|
||||
double height});
|
||||
}
|
||||
|
||||
class _$ProjectScreenCopyWithImpl<$Res>
|
||||
extends _$ProjectWidgetCopyWithImpl<$Res>
|
||||
implements $ProjectScreenCopyWith<$Res> {
|
||||
_$ProjectScreenCopyWithImpl(
|
||||
ProjectScreen _value, $Res Function(ProjectScreen) _then)
|
||||
: super(_value, (v) => _then(v as ProjectScreen));
|
||||
|
||||
@override
|
||||
ProjectScreen get _value => super._value as ProjectScreen;
|
||||
|
||||
@override
|
||||
$Res call({
|
||||
Object path = freezed,
|
||||
Object className = freezed,
|
||||
Object isStateful = freezed,
|
||||
Object route = freezed,
|
||||
Object data = freezed,
|
||||
Object tokens = freezed,
|
||||
Object callbacks = freezed,
|
||||
Object dx = freezed,
|
||||
Object dy = freezed,
|
||||
Object width = freezed,
|
||||
Object height = freezed,
|
||||
}) {
|
||||
return _then(ProjectScreen(
|
||||
path: path == freezed ? _value.path : path as String,
|
||||
className: className == freezed ? _value.className : className as String,
|
||||
isStateful:
|
||||
isStateful == freezed ? _value.isStateful : isStateful as bool,
|
||||
route: route == freezed ? _value.route : route as String,
|
||||
data: data == freezed ? _value.data : data as String,
|
||||
tokens: tokens == freezed ? _value.tokens : tokens as List<String>,
|
||||
callbacks:
|
||||
callbacks == freezed ? _value.callbacks : callbacks as List<String>,
|
||||
dx: dx == freezed ? _value.dx : dx as double,
|
||||
dy: dy == freezed ? _value.dy : dy as double,
|
||||
width: width == freezed ? _value.width : width as double,
|
||||
height: height == freezed ? _value.height : height as double,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class _$ProjectScreen with DiagnosticableTreeMixin implements ProjectScreen {
|
||||
_$ProjectScreen(
|
||||
{this.path,
|
||||
this.className = 'MyScreen',
|
||||
this.isStateful = false,
|
||||
this.route = '/',
|
||||
this.data,
|
||||
this.tokens,
|
||||
this.callbacks,
|
||||
this.dx,
|
||||
this.dy,
|
||||
this.width,
|
||||
this.height})
|
||||
: assert(className != null),
|
||||
assert(isStateful != null),
|
||||
assert(route != null);
|
||||
|
||||
factory _$ProjectScreen.fromJson(Map<String, dynamic> json) =>
|
||||
_$_$ProjectScreenFromJson(json);
|
||||
|
||||
@override
|
||||
final String path;
|
||||
@JsonKey(defaultValue: 'MyScreen')
|
||||
@override
|
||||
final String className;
|
||||
@JsonKey(defaultValue: false)
|
||||
@override
|
||||
final bool isStateful;
|
||||
@JsonKey(defaultValue: '/')
|
||||
@override
|
||||
final String route;
|
||||
@override
|
||||
final String data;
|
||||
@override
|
||||
final List<String> tokens;
|
||||
@override
|
||||
final List<String> callbacks;
|
||||
@override
|
||||
final double dx;
|
||||
@override
|
||||
final double dy;
|
||||
@override
|
||||
final double width;
|
||||
@override
|
||||
final double height;
|
||||
|
||||
@override
|
||||
String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) {
|
||||
return 'ProjectWidget.screen(path: $path, className: $className, isStateful: $isStateful, route: $route, data: $data, tokens: $tokens, callbacks: $callbacks, dx: $dx, dy: $dy, width: $width, height: $height)';
|
||||
}
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties
|
||||
..add(DiagnosticsProperty('type', 'ProjectWidget.screen'))
|
||||
..add(DiagnosticsProperty('path', path))
|
||||
..add(DiagnosticsProperty('className', className))
|
||||
..add(DiagnosticsProperty('isStateful', isStateful))
|
||||
..add(DiagnosticsProperty('route', route))
|
||||
..add(DiagnosticsProperty('data', data))
|
||||
..add(DiagnosticsProperty('tokens', tokens))
|
||||
..add(DiagnosticsProperty('callbacks', callbacks))
|
||||
..add(DiagnosticsProperty('dx', dx))
|
||||
..add(DiagnosticsProperty('dy', dy))
|
||||
..add(DiagnosticsProperty('width', width))
|
||||
..add(DiagnosticsProperty('height', height));
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(dynamic other) {
|
||||
return identical(this, other) ||
|
||||
(other is ProjectScreen &&
|
||||
(identical(other.path, path) ||
|
||||
const DeepCollectionEquality().equals(other.path, path)) &&
|
||||
(identical(other.className, className) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.className, className)) &&
|
||||
(identical(other.isStateful, isStateful) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.isStateful, isStateful)) &&
|
||||
(identical(other.route, route) ||
|
||||
const DeepCollectionEquality().equals(other.route, route)) &&
|
||||
(identical(other.data, data) ||
|
||||
const DeepCollectionEquality().equals(other.data, data)) &&
|
||||
(identical(other.tokens, tokens) ||
|
||||
const DeepCollectionEquality().equals(other.tokens, tokens)) &&
|
||||
(identical(other.callbacks, callbacks) ||
|
||||
const DeepCollectionEquality()
|
||||
.equals(other.callbacks, callbacks)) &&
|
||||
(identical(other.dx, dx) ||
|
||||
const DeepCollectionEquality().equals(other.dx, dx)) &&
|
||||
(identical(other.dy, dy) ||
|
||||
const DeepCollectionEquality().equals(other.dy, dy)) &&
|
||||
(identical(other.width, width) ||
|
||||
const DeepCollectionEquality().equals(other.width, width)) &&
|
||||
(identical(other.height, height) ||
|
||||
const DeepCollectionEquality().equals(other.height, height)));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
runtimeType.hashCode ^
|
||||
const DeepCollectionEquality().hash(path) ^
|
||||
const DeepCollectionEquality().hash(className) ^
|
||||
const DeepCollectionEquality().hash(isStateful) ^
|
||||
const DeepCollectionEquality().hash(route) ^
|
||||
const DeepCollectionEquality().hash(data) ^
|
||||
const DeepCollectionEquality().hash(tokens) ^
|
||||
const DeepCollectionEquality().hash(callbacks) ^
|
||||
const DeepCollectionEquality().hash(dx) ^
|
||||
const DeepCollectionEquality().hash(dy) ^
|
||||
const DeepCollectionEquality().hash(width) ^
|
||||
const DeepCollectionEquality().hash(height);
|
||||
|
||||
@override
|
||||
$ProjectScreenCopyWith<ProjectScreen> get copyWith =>
|
||||
_$ProjectScreenCopyWithImpl<ProjectScreen>(this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$_$ProjectScreenToJson(this);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ProjectScreen implements ProjectWidget {
|
||||
factory ProjectScreen(
|
||||
{String path,
|
||||
String className,
|
||||
bool isStateful,
|
||||
String route,
|
||||
String data,
|
||||
List<String> tokens,
|
||||
List<String> callbacks,
|
||||
double dx,
|
||||
double dy,
|
||||
double width,
|
||||
double height}) = _$ProjectScreen;
|
||||
|
||||
factory ProjectScreen.fromJson(Map<String, dynamic> json) =
|
||||
_$ProjectScreen.fromJson;
|
||||
|
||||
@override
|
||||
String get path;
|
||||
@override
|
||||
String get className;
|
||||
@override
|
||||
bool get isStateful;
|
||||
@override
|
||||
String get route;
|
||||
@override
|
||||
String get data;
|
||||
@override
|
||||
List<String> get tokens;
|
||||
@override
|
||||
List<String> get callbacks;
|
||||
@override
|
||||
double get dx;
|
||||
@override
|
||||
double get dy;
|
||||
@override
|
||||
double get width;
|
||||
@override
|
||||
double get height;
|
||||
@override
|
||||
$ProjectScreenCopyWith<ProjectScreen> get copyWith;
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'widget.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$ProjectScreen _$_$ProjectScreenFromJson(Map<String, dynamic> json) {
|
||||
return _$ProjectScreen(
|
||||
path: json['path'] as String,
|
||||
className: json['className'] as String ?? 'MyScreen',
|
||||
isStateful: json['isStateful'] as bool ?? false,
|
||||
route: json['route'] as String ?? '/',
|
||||
data: json['data'] as String,
|
||||
tokens: (json['tokens'] as List)?.map((e) => e as String)?.toList(),
|
||||
callbacks: (json['callbacks'] as List)?.map((e) => e as String)?.toList(),
|
||||
dx: (json['dx'] as num)?.toDouble(),
|
||||
dy: (json['dy'] as num)?.toDouble(),
|
||||
width: (json['width'] as num)?.toDouble(),
|
||||
height: (json['height'] as num)?.toDouble(),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> _$_$ProjectScreenToJson(_$ProjectScreen instance) =>
|
||||
<String, dynamic>{
|
||||
'path': instance.path,
|
||||
'className': instance.className,
|
||||
'isStateful': instance.isStateful,
|
||||
'route': instance.route,
|
||||
'data': instance.data,
|
||||
'tokens': instance.tokens,
|
||||
'callbacks': instance.callbacks,
|
||||
'dx': instance.dx,
|
||||
'dy': instance.dy,
|
||||
'width': instance.width,
|
||||
'height': instance.height,
|
||||
};
|
||||
@@ -0,0 +1,254 @@
|
||||
const String readme = """
|
||||
# {{name}}
|
||||
|
||||
{{description}}
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
|
||||
|
||||
For help getting started with Flutter, view our
|
||||
[online documentation](https://flutter.dev/docs), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
|
||||
""";
|
||||
|
||||
const String pubspec = """
|
||||
name: {{name}}
|
||||
description: {{description}}
|
||||
version: 1.0.0+1
|
||||
environment:
|
||||
sdk: ">=2.1.0 <3.0.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
cupertino_icons: ^0.1.2
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
flutter:
|
||||
uses-material-design: true
|
||||
""";
|
||||
|
||||
const String projectIml = """
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://\$MODULE_DIR\$">
|
||||
<sourceFolder url="file://\$MODULE_DIR\$/lib" isTestSource="false" />
|
||||
<sourceFolder url="file://\$MODULE_DIR\$/test" isTestSource="true" />
|
||||
<excludeFolder url="file://\$MODULE_DIR\$/.dart_tool" />
|
||||
<excludeFolder url="file://\$MODULE_DIR\$/.idea" />
|
||||
<excludeFolder url="file://\$MODULE_DIR\$/.pub" />
|
||||
<excludeFolder url="file://\$MODULE_DIR\$/build" />
|
||||
</content>
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Dart SDK" level="project" />
|
||||
<orderEntry type="library" name="Flutter Plugins" level="project" />
|
||||
<orderEntry type="library" name="Dart Packages" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
""";
|
||||
|
||||
const String analysisOptions = """
|
||||
analyzer:
|
||||
exclude: [build/**]
|
||||
errors:
|
||||
uri_has_not_been_generated: ignore
|
||||
plugins:
|
||||
- flutter
|
||||
|
||||
# Lint rules and documentation, see http://dart-lang.github.io/linter/lints
|
||||
linter:
|
||||
rules:
|
||||
- cancel_subscriptions
|
||||
- hash_and_equals
|
||||
- iterable_contains_unrelated_type
|
||||
- list_remove_unrelated_type
|
||||
- test_types_in_equals
|
||||
- unrelated_type_equality_checks
|
||||
- valid_regexps
|
||||
""";
|
||||
|
||||
const String metadata = """
|
||||
# This file tracks properties of this Flutter project.
|
||||
# Used by Flutter tool to assess capabilities and perform upgrades etc.
|
||||
#
|
||||
# This file should be version controlled and should not be manually edited.
|
||||
|
||||
version:
|
||||
revision: ec1044a8773e31b4630bf162d9c374236ad1eaaf
|
||||
channel: master
|
||||
|
||||
project_type: app
|
||||
|
||||
""";
|
||||
|
||||
const String gitignore = """
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.log
|
||||
*.pyc
|
||||
*.swp
|
||||
.DS_Store
|
||||
.atom/
|
||||
.buildlog/
|
||||
.history
|
||||
.svn/
|
||||
|
||||
# IntelliJ related
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
# The .vscode folder contains launch configuration and tasks you configure in
|
||||
# VS Code which you may wish to be included in version control, so this line
|
||||
# is commented out by default.
|
||||
#.vscode/
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
.packages
|
||||
.pub-cache/
|
||||
.pub/
|
||||
/build/
|
||||
|
||||
# Web related
|
||||
lib/generated_plugin_registrant.dart
|
||||
|
||||
# Exceptions to above rules.
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||
|
||||
""";
|
||||
|
||||
const String testFile = """
|
||||
// This is a basic Flutter widget test.
|
||||
//
|
||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||
// utility that Flutter provides. For example, you can send tap and scroll
|
||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:flutter_project/main.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(MyApp());
|
||||
|
||||
// Verify that our counter starts at 0.
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(find.text('1'), findsNothing);
|
||||
|
||||
// Tap the '+' icon and trigger a frame.
|
||||
await tester.tap(find.byIcon(Icons.add));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that our counter has incremented.
|
||||
expect(find.text('0'), findsNothing);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
||||
""";
|
||||
|
||||
const String mainFile = """
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'ui/{{screenFile}}/screen.dart';
|
||||
|
||||
void main() => runApp(MyApp());
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: '{{name}}',
|
||||
theme: ThemeData.light(),
|
||||
darkTheme: ThemeData.dark(),
|
||||
home: {{screenClassName}}(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
""";
|
||||
|
||||
const String webManifest = """
|
||||
{
|
||||
"name": "{{name}}",
|
||||
"short_name": "{{name}}",
|
||||
"start_url": ".",
|
||||
"display": "minimal-ui",
|
||||
"background_color": "#0175C2",
|
||||
"theme_color": "#0175C2",
|
||||
"description": "{{description}}",
|
||||
"orientation": "portrait-primary",
|
||||
"prefer_related_applications": false,
|
||||
"icons": [
|
||||
{
|
||||
"src": "icons/Icon-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/Icon-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
""";
|
||||
|
||||
const String webIndex = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||
<meta name="description" content="{{description}}">
|
||||
|
||||
<!-- iOS meta tags & icons -->
|
||||
<link rel="icon" type="image/png" href="favicon.png">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="flutter_project">
|
||||
<link rel="apple-touch-icon" href="/icons/Icon-192.png">
|
||||
|
||||
<title>{{name}}</title>
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
</head>
|
||||
<body>
|
||||
<!-- This script installs service_worker.js to provide PWA functionality to
|
||||
application. For more information, see:
|
||||
https://developers.google.com/web/fundamentals/primers/service-workers -->
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function () {
|
||||
navigator.serviceWorker.register('/flutter_service_worker.js');
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<script src="main.dart.js" type="application/javascript"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
""";
|
||||
@@ -0,0 +1,127 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:archive/archive.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:image_resizer/image_resizer.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import 'files/files.dart';
|
||||
import 'project/project.dart';
|
||||
|
||||
class ProjectBase {
|
||||
ProjectBase({
|
||||
this.files,
|
||||
this.meta,
|
||||
this.path,
|
||||
});
|
||||
|
||||
List<ProjectFileBase> files;
|
||||
FlutterProject meta;
|
||||
String path;
|
||||
|
||||
Future<List<int>> generateArchive() async {
|
||||
final List<FileData> _files = [];
|
||||
for (var file in files) {
|
||||
_files.addAll(await _readDir(file.path, file));
|
||||
}
|
||||
for (var file in _files) {
|
||||
print('p: ${file.path}}');
|
||||
}
|
||||
var encoder = ZipEncoder();
|
||||
final _output = OutputStream();
|
||||
encoder.startEncode(_output);
|
||||
for (var f in _files) {
|
||||
final archiveFile = ArchiveFile(f.path, f.size, f.data);
|
||||
encoder.addFile(archiveFile);
|
||||
}
|
||||
encoder.endEncode();
|
||||
return _output.getBytes();
|
||||
}
|
||||
|
||||
Future<List<FileData>> _readDir(String dir, ProjectFileBase file) async {
|
||||
final List<FileData> _files = [];
|
||||
if (file is ProjectFile) {
|
||||
// print('file: ${file.path}');
|
||||
_files.add(await file.getFileData());
|
||||
}
|
||||
if (file is ProjectDirectory) {
|
||||
// print('dir: ${file.path}');
|
||||
for (var child in file.children) {
|
||||
// print('dir-file: ${child.path}');
|
||||
_files.addAll(await _readDir(p.join(dir, file.path), child));
|
||||
}
|
||||
}
|
||||
return _files;
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ProjectFileBase {
|
||||
final String path;
|
||||
String get filename => path.split('/').last;
|
||||
String get ext => filename.split('.').last;
|
||||
String get name => filename.split('.').first;
|
||||
ProjectFileBase(this.path);
|
||||
}
|
||||
|
||||
class ProjectFile extends ProjectFileBase {
|
||||
ProjectFile(String path, this.readAsBytes) : super(path);
|
||||
|
||||
Future init() async => update(await readAsBytes);
|
||||
|
||||
final _htmlOutput = ValueNotifier<String>(null);
|
||||
|
||||
Future<bool> save() async {
|
||||
if (contentChanged.value) {
|
||||
final _bytes = content.value;
|
||||
await updateLocalFile(path, _bytes);
|
||||
contentChanged.value = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void refresh() async {
|
||||
final _newBytes = await refreshLocalFile(path);
|
||||
update(_newBytes);
|
||||
}
|
||||
|
||||
Future<List<int>> get bytes async {
|
||||
final _changed = _content.value;
|
||||
final _saved = await readAsBytes;
|
||||
return _changed ?? _saved;
|
||||
}
|
||||
|
||||
final Future<List<int>> readAsBytes;
|
||||
ValueListenable<List<int>> get content => _content;
|
||||
final _content = ValueNotifier<List<int>>(null);
|
||||
|
||||
void update(List<int> data) async {
|
||||
_content.value = data;
|
||||
if (data != await readAsBytes) {
|
||||
contentChanged.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
final contentChanged = ValueNotifier<bool>(false);
|
||||
|
||||
Future<FileData> getFileData() async {
|
||||
List<int> _data;
|
||||
if (content.value != null) {
|
||||
_data = content.value;
|
||||
} else if (readAsBytes != null) {
|
||||
_data = await readAsBytes;
|
||||
}
|
||||
return FileData(
|
||||
_data,
|
||||
_data.length,
|
||||
filename,
|
||||
path,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ProjectDirectory extends ProjectFileBase {
|
||||
final List<ProjectFileBase> children;
|
||||
|
||||
ProjectDirectory(String path, this.children) : super(path);
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import 'constants.dart';
|
||||
import 'project/project.dart';
|
||||
import 'project_constants.dart';
|
||||
import 'project_files.dart';
|
||||
import 'template_gen.dart';
|
||||
|
||||
class TemplateGen {
|
||||
TemplateGen._();
|
||||
|
||||
static TemplateGen get instance => TemplateGen._();
|
||||
|
||||
static final _log = Logger('TemplateGen');
|
||||
|
||||
static Future<String> loadTemplate(String path, [bool cache = true]) =>
|
||||
rootBundle.loadString(path, cache: cache).catchError((e, stackTrace) =>
|
||||
_log.severe('Error Loading Template!', e, stackTrace));
|
||||
|
||||
static String replaceTokens(String source,
|
||||
[Map<String, dynamic> tokens, String name]) {
|
||||
final _gen = TemplateGenerator();
|
||||
return _gen.replaceTokens(source, tokens: tokens, name: name);
|
||||
}
|
||||
|
||||
static String generateWidget(String className,
|
||||
{String childWidget, bool isStateful = false}) {
|
||||
return replaceTokens(
|
||||
isStateful ? statefulWidgetData : statelessWidgetData, {
|
||||
"className": className,
|
||||
"hasChild": childWidget != null,
|
||||
"childWidget": childWidget,
|
||||
});
|
||||
}
|
||||
|
||||
static String generateAppPreview(String className, String childWidget,
|
||||
{ThemeMode themeMode = ThemeMode.system}) {
|
||||
return kDefaultAppWidget
|
||||
.replaceAll('{{className}}', className)
|
||||
.replaceAll('{{childWidget}}', childWidget)
|
||||
.replaceAll('{{themeMode}}', describeEnum(themeMode));
|
||||
// return replaceTokens(kDefaultAppWidget, {
|
||||
// "className": className,
|
||||
// "childWidget": childWidget,
|
||||
// });
|
||||
}
|
||||
|
||||
static ProjectBase generateProject([FlutterProject base]) {
|
||||
FlutterProject _base = base ?? FlutterProject();
|
||||
_base = _base.copyWith(path: '');
|
||||
final _path = _base.path;
|
||||
final _data = <String, dynamic>{
|
||||
'screenClassName': 'HomeScreen',
|
||||
'screenFile': 'home',
|
||||
"className": 'HomeScreen',
|
||||
'name': _base.name,
|
||||
'description': _base.description,
|
||||
"hasChild": false,
|
||||
};
|
||||
final _project = ProjectBase();
|
||||
_project.meta = _base;
|
||||
_project.files = [
|
||||
ProjectDirectory(p.join(_path, 'test'), [
|
||||
_addFile(p.join(_path, 'test', 'widget_test.dart'), testFile, _data),
|
||||
]),
|
||||
ProjectDirectory(p.join(_path, 'lib'), [
|
||||
_addFile(p.join(_path, 'lib', 'main.dart'), mainFile, _data),
|
||||
ProjectDirectory(p.join(_path, 'lib', 'ui'), [
|
||||
ProjectDirectory(p.join(_path, 'lib', 'ui', 'home'), [
|
||||
_addFile(p.join(_path, 'lib', 'ui', 'home', 'screen.dart'),
|
||||
counterExample, _data),
|
||||
]),
|
||||
]),
|
||||
]),
|
||||
ProjectDirectory(p.join(_path, 'web'), [
|
||||
_addFile(p.join(_path, 'web', 'index.html'), webIndex, _data),
|
||||
_addFile(p.join(_path, 'web', 'manifest.json'), webManifest, _data),
|
||||
]),
|
||||
_addFile(p.join(_path, '.gitignore'), gitignore, _data),
|
||||
_addFile(p.join(_path, '.metadata'), metadata, _data),
|
||||
_addFile(p.join(_path, 'analysis_options.yaml'), analysisOptions, _data),
|
||||
_addFile(p.join(_path, 'project.iml'), projectIml, _data),
|
||||
_addFile(p.join(_path, 'pubspec.yaml'), pubspec, _data),
|
||||
_addFile(p.join(_path, 'README.md'), readme, _data),
|
||||
];
|
||||
return _project;
|
||||
}
|
||||
|
||||
static ProjectFile _addFile(
|
||||
String filename, String source, Map<String, dynamic> _data) {
|
||||
final _content = utf8.encode(replaceTokens(source, _data));
|
||||
final _file = ProjectFile(filename, Future.value(_content));
|
||||
_file.update(_content);
|
||||
return _file;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
library template_gen;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:reflected_mustache/mustache.dart';
|
||||
|
||||
class TemplateGenerator {
|
||||
String replaceTokens(
|
||||
String source, {
|
||||
Map<String, dynamic> tokens,
|
||||
String name,
|
||||
bool silentErrors = true,
|
||||
bool htmlEscapeValues =false,
|
||||
String delimiters,
|
||||
bool lenient = false,
|
||||
Template Function(String) partialResolver,
|
||||
}) {
|
||||
final template = Template(
|
||||
source,
|
||||
name: name,
|
||||
lenient: lenient,
|
||||
htmlEscapeValues: htmlEscapeValues,
|
||||
delimiters: delimiters,
|
||||
partialResolver: partialResolver,
|
||||
);
|
||||
if (!silentErrors) {
|
||||
return template.renderString(tokens ?? '');
|
||||
}
|
||||
try {
|
||||
return template.renderString(tokens ?? '');
|
||||
} on TemplateException catch (e) {
|
||||
debugPrint("Error Swapping Tokens! $e");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user