Settings
This commit is contained in:
parent
dab542e652
commit
a1db40aab1
|
|
@ -156,7 +156,7 @@ class _EmailSettingsState extends State<EmailSettings>
|
|||
label: localization.enableMarkup,
|
||||
helpLabel: localization.enableMarkupHelp,
|
||||
value: settings.enableEmailMarkup,
|
||||
iconData: FontAwesomeIcons.envelope,
|
||||
iconData: FontAwesomeIcons.solidEnvelope,
|
||||
showBlank: state.settingsUIState.isFiltered,
|
||||
onChanged: (value) => viewModel.onSettingsChanged(
|
||||
settings.rebuild((b) => b..enableEmailMarkup = value)),
|
||||
|
|
|
|||
|
|
@ -1,10 +1,30 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/forms/app_form.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/forms/decorated_form_field.dart';
|
||||
import 'package:invoiceninja_flutter/ui/settings/settings_scaffold.dart';
|
||||
import 'package:invoiceninja_flutter/ui/settings/templates_and_reminders_vm.dart';
|
||||
import 'package:invoiceninja_flutter/utils/localization.dart';
|
||||
import 'package:invoiceninja_flutter/utils/platforms.dart';
|
||||
import 'package:webview_flutter/webview_flutter.dart';
|
||||
|
||||
const String kExamplePage = '''
|
||||
<!DOCTYPE html><html>
|
||||
<head><title>Navigation Delegate Example</title></head>
|
||||
<body>
|
||||
<p>
|
||||
The navigation delegate is set to block navigation to the youtube website.
|
||||
</p>
|
||||
<ul>
|
||||
<ul><a href="https://www.youtube.com/">https://www.youtube.com/</a></ul>
|
||||
<ul><a href="https://www.google.com/">https://www.google.com/</a></ul>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
''';
|
||||
|
||||
class TemplatesAndReminders extends StatefulWidget {
|
||||
const TemplatesAndReminders({
|
||||
|
|
@ -18,12 +38,10 @@ class TemplatesAndReminders extends StatefulWidget {
|
|||
_TemplatesAndRemindersState createState() => _TemplatesAndRemindersState();
|
||||
}
|
||||
|
||||
class _TemplatesAndRemindersState extends State<TemplatesAndReminders>
|
||||
with SingleTickerProviderStateMixin {
|
||||
class _TemplatesAndRemindersState extends State<TemplatesAndReminders> {
|
||||
static final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
|
||||
|
||||
FocusScopeNode _focusNode;
|
||||
TabController _controller;
|
||||
|
||||
bool autoValidate = false;
|
||||
|
||||
|
|
@ -35,13 +53,11 @@ class _TemplatesAndRemindersState extends State<TemplatesAndReminders>
|
|||
void initState() {
|
||||
super.initState();
|
||||
_focusNode = FocusScopeNode();
|
||||
_controller = TabController(vsync: this, length: 7);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_focusNode.dispose();
|
||||
_controller.dispose();
|
||||
_controllers.forEach((dynamic controller) {
|
||||
controller.removeListener(_onChanged);
|
||||
controller.dispose();
|
||||
|
|
@ -82,62 +98,148 @@ class _TemplatesAndRemindersState extends State<TemplatesAndReminders>
|
|||
final localization = AppLocalization.of(context);
|
||||
final viewModel = widget.viewModel;
|
||||
final state = viewModel.state;
|
||||
final settings = viewModel.settings;
|
||||
|
||||
final String contentBase64 =
|
||||
base64Encode(const Utf8Encoder().convert(kExamplePage));
|
||||
final url = 'data:text/html;base64,$contentBase64';
|
||||
print('url: $url');
|
||||
|
||||
|
||||
return SettingsScaffold(
|
||||
title: localization.templatesAndReminders,
|
||||
onSavePressed: viewModel.onSavePressed,
|
||||
appBarBottom: TabBar(
|
||||
key: ValueKey(state.settingsUIState.updatedAt),
|
||||
controller: _controller,
|
||||
isScrollable: true,
|
||||
tabs: [
|
||||
Tab(
|
||||
text: localization.invoices,
|
||||
),
|
||||
Tab(
|
||||
text: localization.quotes,
|
||||
),
|
||||
Tab(
|
||||
text: localization.payments,
|
||||
),
|
||||
Tab(
|
||||
text: localization.firstReminder,
|
||||
),
|
||||
Tab(
|
||||
text: localization.secondReminder,
|
||||
),
|
||||
Tab(
|
||||
text: localization.thirdReminder,
|
||||
),
|
||||
Tab(
|
||||
text: localization.endlessReminder,
|
||||
),
|
||||
],
|
||||
),
|
||||
body: AppTabForm(
|
||||
tabController: _controller,
|
||||
formKey: _formKey,
|
||||
focusNode: _focusNode,
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
TemplateEditor(),
|
||||
TemplateEditor(),
|
||||
TemplateEditor(),
|
||||
TemplateEditor(),
|
||||
TemplateEditor(),
|
||||
TemplateEditor(),
|
||||
TemplateEditor(),
|
||||
AppForm(
|
||||
formKey: _formKey,
|
||||
children: <Widget>[
|
||||
FormCard(
|
||||
children: <Widget>[
|
||||
DecoratedFormField(
|
||||
label: localization.subject,
|
||||
//controller: _subjectController,
|
||||
),
|
||||
DecoratedFormField(
|
||||
label: localization.body,
|
||||
//controller: _bodyController,
|
||||
maxLines: 8,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: WebView(
|
||||
initialUrl: url,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TemplateEditor extends StatelessWidget {
|
||||
class TemplateEditor extends StatefulWidget {
|
||||
const TemplateEditor({this.subject, this.body});
|
||||
|
||||
final String subject;
|
||||
final String body;
|
||||
|
||||
@override
|
||||
_TemplateEditorState createState() => _TemplateEditorState();
|
||||
}
|
||||
|
||||
class _TemplateEditorState extends State<TemplateEditor> {
|
||||
|
||||
final Completer<WebViewController> _controller =
|
||||
Completer<WebViewController>();
|
||||
|
||||
final _subjectController = TextEditingController();
|
||||
final _bodyController = TextEditingController();
|
||||
|
||||
List<TextEditingController> _controllers = [];
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
_controllers = [
|
||||
_subjectController,
|
||||
_bodyController,
|
||||
];
|
||||
|
||||
_controllers
|
||||
.forEach((dynamic controller) => controller.removeListener(_onChanged));
|
||||
|
||||
_subjectController.text = widget.subject;
|
||||
_bodyController.text = widget.body;
|
||||
|
||||
_controllers
|
||||
.forEach((dynamic controller) => controller.addListener(_onChanged));
|
||||
|
||||
super.didChangeDependencies();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controllers.forEach((dynamic controller) {
|
||||
controller.removeListener(_onChanged);
|
||||
controller.dispose();
|
||||
});
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onChanged() {
|
||||
print('## CHANGED: ${_subjectController.text} - ${_bodyController.text}');
|
||||
/*
|
||||
final product = widget.viewModel.product.rebuild((b) => b
|
||||
..customValue2 = _custom2Controller.text.trim());
|
||||
if (product != widget.viewModel.product) {
|
||||
widget.viewModel.onChanged(product);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final localization = AppLocalization.of(context);
|
||||
|
||||
return ListView(
|
||||
children: <Widget>[
|
||||
Text('test')
|
||||
FormCard(
|
||||
children: <Widget>[
|
||||
DecoratedFormField(
|
||||
label: localization.subject,
|
||||
controller: _subjectController,
|
||||
),
|
||||
DecoratedFormField(
|
||||
label: localization.body,
|
||||
controller: _bodyController,
|
||||
maxLines: 8,
|
||||
),
|
||||
],
|
||||
),
|
||||
FormCard(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
WebView(
|
||||
//initialUrl: url,
|
||||
initialUrl: 'https://flutter.dev',
|
||||
javascriptMode: JavascriptMode.unrestricted,
|
||||
onWebViewCreated: (WebViewController webViewController) {
|
||||
_controller.complete(webViewController);
|
||||
},
|
||||
onPageFinished: (String url) {
|
||||
print('Page finished loading: $url');
|
||||
},
|
||||
),
|
||||
Text('subject'),
|
||||
SizedBox(height: 15),
|
||||
Text('body'),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
59
pubspec.lock
59
pubspec.lock
|
|
@ -14,7 +14,7 @@ packages:
|
|||
name: analyzer_plugin
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
version: "0.2.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -42,7 +42,7 @@ packages:
|
|||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -63,7 +63,7 @@ packages:
|
|||
name: build_resolvers
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.2.1"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
|
|
@ -91,21 +91,21 @@ packages:
|
|||
name: built_value
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.7.1"
|
||||
version: "6.8.2"
|
||||
built_value_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: built_value_generator
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.7.1"
|
||||
version: "6.8.2"
|
||||
cached_network_image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cached_network_image
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.1.2+1"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -217,7 +217,7 @@ packages:
|
|||
name: fixnum
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.9"
|
||||
version: "0.10.11"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
|
@ -229,7 +229,7 @@ packages:
|
|||
name: flutter_cache_manager
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
version: "1.1.3"
|
||||
flutter_colorpicker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -267,7 +267,7 @@ packages:
|
|||
name: flutter_slidable
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.3"
|
||||
version: "0.5.4"
|
||||
flutter_test:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
|
@ -298,14 +298,14 @@ packages:
|
|||
name: glob
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.7"
|
||||
version: "1.2.0"
|
||||
google_sign_in:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: google_sign_in
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.7"
|
||||
version: "4.0.11"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -347,14 +347,14 @@ packages:
|
|||
name: image_picker
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.1+4"
|
||||
version: "0.6.1+10"
|
||||
in_app_purchase:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: in_app_purchase
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.1+4"
|
||||
version: "0.2.2+2"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
@ -453,6 +453,20 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
node_interop:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_interop
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
node_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1+2"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -494,7 +508,7 @@ packages:
|
|||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.4.0"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -578,21 +592,21 @@ packages:
|
|||
name: sentry
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "2.3.1"
|
||||
share:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: share
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.2+1"
|
||||
version: "0.6.3+1"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.3+4"
|
||||
version: "0.5.4+3"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -660,7 +674,7 @@ packages:
|
|||
name: sqflite
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.7"
|
||||
version: "1.1.7+2"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -744,7 +758,7 @@ packages:
|
|||
name: url_launcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.1.4"
|
||||
version: "5.2.1"
|
||||
usage:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -787,6 +801,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.15"
|
||||
webview_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: webview_flutter
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.15+1"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ dependencies:
|
|||
native_pdf_renderer: any
|
||||
flutter_colorpicker: any
|
||||
flutter_json_widget: ^1.0.2
|
||||
webview_flutter: ^0.3.15+1
|
||||
#quick_actions: ^0.2.1
|
||||
|
||||
dev_dependencies:
|
||||
|
|
|
|||
Loading…
Reference in New Issue