Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
bats64mgutsi committed Mar 1, 2021
2 parents 207b4fb + 4d2c303 commit 68d9a85
Show file tree
Hide file tree
Showing 24 changed files with 664 additions and 24 deletions.
6 changes: 6 additions & 0 deletions packages/stacked/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 1.9.2

### MAJOR UPDATE: FORMS!!!

- Adds brand new form first party support and form generation functionality

## 1.9.1+2

- Fix null error from locator
Expand Down
5 changes: 4 additions & 1 deletion packages/stacked/example/lib/app/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import 'package:new_architecture/ui/bottom_nav/bottom_nav_example.dart';
import 'package:new_architecture/ui/bottom_nav/favorites/favorites_viewmodel.dart';
import 'package:new_architecture/ui/bottom_nav/history/history_viewmodel.dart';
import 'package:new_architecture/ui/details/details_view.dart';
import 'package:new_architecture/ui/form/example_form_view.dart';
import 'package:new_architecture/ui/home/home_view.dart';
import 'package:new_architecture/ui/stream_view/stream_counter_view.dart';
import 'package:stacked/stacked_annotations.dart';
import 'package:stacked_services/stacked_services.dart';

@StackedApp(
routes: [
MaterialRoute(page: HomeView, initial: true),
MaterialRoute(page: HomeView),
MaterialRoute(page: BottomNavExample),
MaterialRoute(page: StreamCounterView),
CupertinoRoute(page: DetailsView),
// TODO: Change the name of the FormView to avoid type clashing
MaterialRoute(page: ExampleFormView, initial: true),
],
dependencies: [
// Lazy singletons
Expand Down
4 changes: 2 additions & 2 deletions packages/stacked/example/lib/app/app.locator.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

153 changes: 153 additions & 0 deletions packages/stacked/example/lib/app/app.logger.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/// Maybe this should be generated for the user as well?
///
/// import 'package:customer_app/services/stackdriver/stackdriver_service.dart';
import 'package:flutter/foundation.dart';
import 'package:logger/logger.dart';
// import 'dart:developer' as logger;

List<String> exludeLogs = [];
String showOnlyClass;

class SimpleLogPrinter extends LogPrinter {
final String className;
final bool printCallingFunctionName;
final bool printCallStack;

SimpleLogPrinter(
this.className, {
this.printCallingFunctionName = true,
this.printCallStack = false,
});

@override
List<String> log(LogEvent event) {
var color = PrettyPrinter.levelColors[event.level];
var emoji = PrettyPrinter.levelEmojis[event.level];
var methodName = _getMethodName();

var methodNameSection =
printCallingFunctionName && methodName != null ? ' | $methodName ' : '';
var stackLog = event.stackTrace.toString();
var output =
'$emoji $className$methodNameSection - ${event.message}${printCallStack ? '\nSTACKTRACE:\n$stackLog' : ''}';

if (exludeLogs.any((excludeClass) => className == excludeClass) ||
(showOnlyClass != null && className != showOnlyClass)) return [];

final pattern = RegExp('.{1,800}'); // 800 is the size of each chunk
List<String> result = [];

for (var line in output.split('\n')) {
result.addAll(pattern.allMatches(line).map((match) {
if (kReleaseMode) {
return match.group(0);
} else {
return color(match.group(0));
}
}));
}

return result;
}

String _getMethodName() {
try {
var currentStack = StackTrace.current;
var formattedStacktrace = formatStackTrace(currentStack, 3);

var realFirstLine =
formattedStacktrace.firstWhere((line) => line.contains(className));

var methodName = realFirstLine.replaceAll('$className.', '');
return methodName;
} catch (e) {
// There's no deliberate function call from our code so we return null;
return null;
}
}
}

final stackTraceRegex = RegExp(r'#[0-9]+[\s]+(.+) \(([^\s]+)\)');

List<String> formatStackTrace(StackTrace stackTrace, int methodCount) {
var lines = stackTrace.toString().split("\n");

var formatted = <String>[];
var count = 0;
for (var line in lines) {
var match = stackTraceRegex.matchAsPrefix(line);
if (match != null) {
if (match.group(2).startsWith('package:logger')) {
continue;
}
var newLine = ("${match.group(1)}");
formatted.add(newLine.replaceAll('<anonymous closure>', '()'));
if (++count == methodCount) {
break;
}
} else {
formatted.add(line);
}
}

if (formatted.isEmpty) {
return null;
} else {
return formatted;
}
}

class MultipleLoggerOutput extends LogOutput {
final List<LogOutput> logOutputs;
MultipleLoggerOutput(this.logOutputs);

@override
void output(OutputEvent event) {
for (var logOutput in logOutputs) {
try {
logOutput.output(event);
} catch (e) {
print('Log output failed');
}
}
}
}

// class StackDriverOutput extends LogOutput {
// @override
// void output(OutputEvent event) {
// try {
// if (event.level != Level.debug) {
// if (locator.isRegistered<StackDriverService>()) {
// locator<StackDriverService>().writeEntry(event.level, event.lines);
// }
// }
// } catch (e) {
// print('STACKDRIVER FAILED: $e');
// }
// }
// }

class LogAllTheTimeFilter extends LogFilter {
@override
bool shouldLog(LogEvent event) {
return true;
}
}

Logger getLogger(String className,
{bool printCallingFunctionName = true, bool printCallstack = false}) {
return Logger(
filter: LogAllTheTimeFilter(),
// printer: SimplePrinter(colors: false),
printer: SimpleLogPrinter(
className,
printCallingFunctionName: printCallingFunctionName,
printCallStack: printCallstack,
),
output: MultipleLoggerOutput([
ConsoleOutput(),
// StackDriverOutput(),
]),
);
}
21 changes: 20 additions & 1 deletion packages/stacked/example/lib/app/app.router.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions packages/stacked/example/lib/ui/form/example_form_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked/stacked_annotations.dart';

import 'example_form_view.form.dart';
import 'example_form_viewmodel.dart';

// #1: Add the annotation
@FormView(fields: [
FormTextField(name: 'email'),
FormTextField(name: 'password', isPassword: true),
])
// #2: with $ExampleFormView
class ExampleFormView extends StatelessWidget with $ExampleFormView {
ExampleFormView({Key key}) : super(key: key);

@override
Widget build(BuildContext context) {
return ViewModelBuilder<ExampleFormViewModel>.reactive(
onModelReady: (model) {
// #3: Listen to text updates by calling listenToFormUpdated(model);
listenToFormUpdated(model);
},
builder: (context, model, child) => Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
model.navigateSomewhere();
},
),
body: Form(
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: <Widget>[
TextFormField(
//#4: Set email emailController and focus node
controller: emailController,
focusNode: emailFocusNode,
),
SizedBox(height: 15),
TextFormField(
//#4: Set email emailController and focus node
controller: passwordController,
focusNode: passwordFocusNode,
onFieldSubmitted: (_) => model.saveData(),
),
SizedBox(height: 15),
if (model.showValidation)
Text(
model.validationMessage,
style: TextStyle(color: Colors.red),
)
],
),
),
),
viewModelBuilder: () => ExampleFormViewModel(),
);
}
}
48 changes: 48 additions & 0 deletions packages/stacked/example/lib/ui/form/example_form_view.form.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 68d9a85

Please # to comment.