Starter...

This commit is contained in:
Hillel Coren 2020-03-02 21:41:03 +02:00
parent b6a2c51153
commit e895d00981
8 changed files with 183 additions and 145 deletions

View File

@ -68,6 +68,10 @@ abstract class CreditUIState extends Object
@nullable @nullable
InvoiceEntity get editing; InvoiceEntity get editing;
@nullable
@BuiltValueField(serialize: false)
int get editingItemIndex;
@override @override
bool get isCreatingNew => editing.isNew; bool get isCreatingNew => editing.isNew;

View File

@ -255,6 +255,8 @@ class _$CreditUIState extends CreditUIState {
@override @override
final InvoiceEntity editing; final InvoiceEntity editing;
@override @override
final int editingItemIndex;
@override
final ListUIState listUIState; final ListUIState listUIState;
@override @override
final String selectedId; final String selectedId;
@ -268,6 +270,7 @@ class _$CreditUIState extends CreditUIState {
_$CreditUIState._( _$CreditUIState._(
{this.editing, {this.editing,
this.editingItemIndex,
this.listUIState, this.listUIState,
this.selectedId, this.selectedId,
this.saveCompleter, this.saveCompleter,
@ -290,6 +293,7 @@ class _$CreditUIState extends CreditUIState {
if (identical(other, this)) return true; if (identical(other, this)) return true;
return other is CreditUIState && return other is CreditUIState &&
editing == other.editing && editing == other.editing &&
editingItemIndex == other.editingItemIndex &&
listUIState == other.listUIState && listUIState == other.listUIState &&
selectedId == other.selectedId && selectedId == other.selectedId &&
saveCompleter == other.saveCompleter && saveCompleter == other.saveCompleter &&
@ -300,7 +304,9 @@ class _$CreditUIState extends CreditUIState {
int get hashCode { int get hashCode {
return $jf($jc( return $jf($jc(
$jc( $jc(
$jc($jc($jc(0, editing.hashCode), listUIState.hashCode), $jc(
$jc($jc($jc(0, editing.hashCode), editingItemIndex.hashCode),
listUIState.hashCode),
selectedId.hashCode), selectedId.hashCode),
saveCompleter.hashCode), saveCompleter.hashCode),
cancelCompleter.hashCode)); cancelCompleter.hashCode));
@ -310,6 +316,7 @@ class _$CreditUIState extends CreditUIState {
String toString() { String toString() {
return (newBuiltValueToStringHelper('CreditUIState') return (newBuiltValueToStringHelper('CreditUIState')
..add('editing', editing) ..add('editing', editing)
..add('editingItemIndex', editingItemIndex)
..add('listUIState', listUIState) ..add('listUIState', listUIState)
..add('selectedId', selectedId) ..add('selectedId', selectedId)
..add('saveCompleter', saveCompleter) ..add('saveCompleter', saveCompleter)
@ -327,6 +334,11 @@ class CreditUIStateBuilder
_$this._editing ??= new InvoiceEntityBuilder(); _$this._editing ??= new InvoiceEntityBuilder();
set editing(InvoiceEntityBuilder editing) => _$this._editing = editing; set editing(InvoiceEntityBuilder editing) => _$this._editing = editing;
int _editingItemIndex;
int get editingItemIndex => _$this._editingItemIndex;
set editingItemIndex(int editingItemIndex) =>
_$this._editingItemIndex = editingItemIndex;
ListUIStateBuilder _listUIState; ListUIStateBuilder _listUIState;
ListUIStateBuilder get listUIState => ListUIStateBuilder get listUIState =>
_$this._listUIState ??= new ListUIStateBuilder(); _$this._listUIState ??= new ListUIStateBuilder();
@ -352,6 +364,7 @@ class CreditUIStateBuilder
CreditUIStateBuilder get _$this { CreditUIStateBuilder get _$this {
if (_$v != null) { if (_$v != null) {
_editing = _$v.editing?.toBuilder(); _editing = _$v.editing?.toBuilder();
_editingItemIndex = _$v.editingItemIndex;
_listUIState = _$v.listUIState?.toBuilder(); _listUIState = _$v.listUIState?.toBuilder();
_selectedId = _$v.selectedId; _selectedId = _$v.selectedId;
_saveCompleter = _$v.saveCompleter; _saveCompleter = _$v.saveCompleter;
@ -381,6 +394,7 @@ class CreditUIStateBuilder
_$result = _$v ?? _$result = _$v ??
new _$CreditUIState._( new _$CreditUIState._(
editing: _editing?.build(), editing: _editing?.build(),
editingItemIndex: editingItemIndex,
listUIState: listUIState.build(), listUIState: listUIState.build(),
selectedId: selectedId, selectedId: selectedId,
saveCompleter: saveCompleter, saveCompleter: saveCompleter,
@ -390,6 +404,7 @@ class CreditUIStateBuilder
try { try {
_$failedField = 'editing'; _$failedField = 'editing';
_editing?.build(); _editing?.build();
_$failedField = 'listUIState'; _$failedField = 'listUIState';
listUIState.build(); listUIState.build();
} catch (e) { } catch (e) {

View File

@ -2,20 +2,21 @@ import 'dart:async';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart'; import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart';
import 'package:invoiceninja_flutter/ui/credit/credit_screen.dart'; import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/credit/edit/credit_edit.dart';
import 'package:invoiceninja_flutter/ui/invoice/edit/invoice_edit_vm.dart';
import 'package:invoiceninja_flutter/ui/credit/view/credit_view_vm.dart';
import 'package:invoiceninja_flutter/utils/platforms.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart'; import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/credit/view/credit_view_vm.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
import 'package:invoiceninja_flutter/data/models/credit_model.dart';
import 'package:invoiceninja_flutter/ui/credit/edit/credit_edit.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class CreditEditScreen extends StatelessWidget { class CreditEditScreen extends StatelessWidget {
const CreditEditScreen({Key key}) : super(key: key); const CreditEditScreen({Key key}) : super(key: key);
static const String route = '/credit/edit'; static const String route = '/credit/edit';
@override @override
@ -27,60 +28,59 @@ class CreditEditScreen extends StatelessWidget {
builder: (context, viewModel) { builder: (context, viewModel) {
return CreditEdit( return CreditEdit(
viewModel: viewModel, viewModel: viewModel,
key: ValueKey(viewModel.credit.id),
); );
}, },
); );
} }
} }
class CreditEditVM { class CreditEditVM extends EntityEditVM {
CreditEditVM({ CreditEditVM({
@required this.state, AppState state,
@required this.credit, CompanyEntity company,
@required this.company, InvoiceEntity invoice,
@required this.onChanged, int invoiceItemIndex,
@required this.isSaving, InvoiceEntity origInvoice,
@required this.origCredit, Function(BuildContext) onSavePressed,
@required this.onSavePressed, Function(List<InvoiceItemEntity>, String) onItemsAdded,
@required this.onCancelPressed, bool isSaving,
@required this.isLoading, Function(BuildContext) onCancelPressed,
}); }) : super(
state: state,
company: company,
invoice: invoice,
invoiceItemIndex: invoiceItemIndex,
origInvoice: origInvoice,
onSavePressed: onSavePressed,
onItemsAdded: onItemsAdded,
isSaving: isSaving,
onCancelPressed: onCancelPressed,
);
factory CreditEditVM.fromStore(Store<AppState> store) { factory CreditEditVM.fromStore(Store<AppState> store) {
final state = store.state; final AppState state = store.state;
final credit = state.creditUIState.editing; final credit = state.creditUIState.editing;
return CreditEditVM( return CreditEditVM(
state: state, state: state,
isLoading: state.isLoading, company: state.company,
isSaving: state.isSaving, isSaving: state.isSaving,
origCredit: state.creditState.map[credit.id], invoice: credit,
credit: credit, invoiceItemIndex: state.creditUIState.editingItemIndex,
company: state.selectedCompany, origInvoice: store.state.creditState.map[credit.id],
onChanged: (InvoiceEntity credit) {
store.dispatch(UpdateCredit(credit));
},
onCancelPressed: (BuildContext context) {
store.dispatch(
EditCredit(credit: InvoiceEntity(), context: context, force: true));
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
},
onSavePressed: (BuildContext context) { onSavePressed: (BuildContext context) {
final Completer<InvoiceEntity> completer = new Completer<InvoiceEntity>(); final Completer<InvoiceEntity> completer = Completer<InvoiceEntity>();
store.dispatch(SaveCreditRequest(completer: completer, credit: credit)); store.dispatch(SaveCreditRequest(completer: completer, credit: credit));
return completer.future.then((savedCredit) { return completer.future.then((savedCredit) {
if (isMobile(context)) { if (isMobile(context)) {
store.dispatch(UpdateCurrentRoute(CreditViewScreen.route)); store.dispatch(UpdateCurrentRoute(CreditViewScreen.route));
if (credit.isNew) { if (credit.isNew) {
Navigator.of(context) Navigator.of(context).pushReplacementNamed(CreditViewScreen.route);
.pushReplacementNamed(CreditViewScreen.route);
} else { } else {
Navigator.of(context).pop(savedCredit); Navigator.of(context).pop(savedCredit);
} }
} else { } else {
store.dispatch(ViewCredit( viewEntity(context: context, entity: savedCredit, force: true);
context: context, creditId: savedCredit.id, force: true));
} }
}).catchError((Object error) { }).catchError((Object error) {
showDialog<ErrorDialog>( showDialog<ErrorDialog>(
@ -90,16 +90,16 @@ class CreditEditVM {
}); });
}); });
}, },
onItemsAdded: (items, clientId) {
if (items.length == 1) {
store.dispatch(EditCreditItem(credit.lineItems.length));
}
store.dispatch(AddCreditItems(items));
},
onCancelPressed: (BuildContext context) {
createEntity(context: context, entity: InvoiceEntity(), force: true);
store.dispatch(UpdateCurrentRoute(state.uiState.previousRoute));
},
); );
} }
final InvoiceEntity credit;
final CompanyEntity company;
final Function(InvoiceEntity) onChanged;
final Function(BuildContext) onSavePressed;
final Function(BuildContext) onCancelPressed;
final bool isLoading;
final bool isSaving;
final InvoiceEntity origCredit;
final AppState state;
} }

View File

@ -1,51 +0,0 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/ui/app/buttons/edit_icon_button.dart';
import 'package:invoiceninja_flutter/ui/app/actions_menu_button.dart';
import 'package:invoiceninja_flutter/ui/credit/view/credit_view_vm.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_state_title.dart';
class CreditView extends StatefulWidget {
const CreditView({
Key key,
@required this.viewModel,
}) : super(key: key);
final CreditViewVM viewModel;
@override
_CreditViewState createState() => new _CreditViewState();
}
class _CreditViewState extends State<CreditView> {
@override
Widget build(BuildContext context) {
final viewModel = widget.viewModel;
final userCompany = viewModel.state.userCompany;
final credit = viewModel.credit;
return Scaffold(
appBar: AppBar(
title: EntityStateTitle(entity: credit),
actions: [
userCompany.canEditEntity(credit)
? EditIconButton(
isVisible: !credit.isDeleted,
onPressed: () => viewModel.onEditPressed(context),
)
: Container(),
ActionMenuButton(
entityActions: credit.getActions(userCompany: userCompany),
isSaving: viewModel.isSaving,
entity: credit,
onSelected: viewModel.onEntityAction,
)
],
),
body: FormCard(children: [
// STARTER: widgets - do not remove comment
]),
);
}
}

View File

@ -1,54 +1,84 @@
import 'dart:async'; import 'dart:async';
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:invoiceninja_flutter/redux/ui/ui_actions.dart'; import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/redux/app/app_actions.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/document/document_actions.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
import 'package:invoiceninja_flutter/ui/app/dialogs/error_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/entities/entity_actions_dialog.dart';
import 'package:invoiceninja_flutter/ui/app/snackbar_row.dart';
import 'package:invoiceninja_flutter/ui/invoice/view/invoice_view.dart';
import 'package:invoiceninja_flutter/ui/invoice/view/invoice_view_vm.dart';
import 'package:invoiceninja_flutter/utils/completers.dart'; import 'package:invoiceninja_flutter/utils/completers.dart';
import 'package:invoiceninja_flutter/ui/credit/credit_screen.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/credit/credit_actions.dart';
import 'package:invoiceninja_flutter/data/models/credit_model.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
import 'package:invoiceninja_flutter/ui/credit/view/credit_view.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
class CreditViewScreen extends StatelessWidget { class CreditViewScreen extends StatelessWidget {
const CreditViewScreen({Key key}) : super(key: key); const CreditViewScreen({Key key}) : super(key: key);
static const String route = '/credit/view'; static const String route = '/credit/view';
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StoreConnector<AppState, CreditViewVM>( return StoreConnector<AppState, CreditViewVM>(
//distinct: true,
converter: (Store<AppState> store) { converter: (Store<AppState> store) {
return CreditViewVM.fromStore(store); return CreditViewVM.fromStore(store);
}, },
builder: (context, vm) { builder: (context, viewModel) {
return CreditView( return InvoiceView(
viewModel: vm, viewModel: viewModel,
); );
}, },
); );
} }
} }
class CreditViewVM { class CreditViewVM extends EntityViewVM {
CreditViewVM({ CreditViewVM({
@required this.state, AppState state,
@required this.credit, CompanyEntity company,
@required this.company, InvoiceEntity invoice,
@required this.onEntityAction, ClientEntity client,
@required this.onRefreshed, bool isSaving,
@required this.isSaving, bool isDirty,
@required this.isLoading, Function(BuildContext, EntityAction) onEntityAction,
@required this.isDirty, Function(BuildContext, [int]) onEditPressed,
}); Function(BuildContext, [bool]) onClientPressed,
Function(BuildContext) onPaymentsPressed,
Function(BuildContext, PaymentEntity) onPaymentPressed,
Function(BuildContext) onRefreshed,
Function(BuildContext, String) onUploadDocument,
Function(BuildContext, DocumentEntity) onDeleteDocument,
Function(BuildContext, DocumentEntity) onViewExpense,
}) : super(
state: state,
company: company,
invoice: invoice,
client: client,
isSaving: isSaving,
isDirty: isDirty,
onActionSelected: onEntityAction,
onEditPressed: onEditPressed,
onClientPressed: onClientPressed,
onPaymentsPressed: onPaymentsPressed,
onPaymentPressed: onPaymentPressed,
onRefreshed: onRefreshed,
onUploadDocument: onUploadDocument,
onDeleteDocument: onDeleteDocument,
onViewExpense: onViewExpense,
);
factory CreditViewVM.fromStore(Store<AppState> store) { factory CreditViewVM.fromStore(Store<AppState> store) {
final state = store.state; final state = store.state;
final credit = state.creditState.map[state.creditUIState.selectedId] ?? final credit = state.creditState.map[state.creditUIState.selectedId] ??
InvoiceEntity(id: state.creditUIState.selectedId); InvoiceEntity(id: state.creditUIState.selectedId);
final client = store.state.clientState.map[credit.clientId] ??
ClientEntity(id: credit.clientId);
Future<Null> _handleRefresh(BuildContext context) { Future<Null> _handleRefresh(BuildContext context) {
final completer = snackBarCompleter<Null>( final completer = snackBarCompleter<Null>(
@ -59,23 +89,58 @@ class CreditViewVM {
return CreditViewVM( return CreditViewVM(
state: state, state: state,
company: state.selectedCompany, company: state.company,
isSaving: state.isSaving, isSaving: state.isSaving,
isLoading: state.isLoading,
isDirty: credit.isNew, isDirty: credit.isNew,
credit: credit, invoice: credit,
client: client,
onEditPressed: (BuildContext context, [int index]) {
editEntity(
context: context,
entity: credit,
subIndex: index,
completer: snackBarCompleter<ClientEntity>(
context, AppLocalization.of(context).updatedCredit));
},
onRefreshed: (context) => _handleRefresh(context), onRefreshed: (context) => _handleRefresh(context),
onClientPressed: (BuildContext context, [bool longPress = false]) {
if (longPress) {
showEntityActionsDialog(
context: context,
entities: [client],
);
} else {
viewEntity(context: context, entity: client);
}
},
onEntityAction: (BuildContext context, EntityAction action) => onEntityAction: (BuildContext context, EntityAction action) =>
handleCreditAction(context, credit, action), handleCreditAction(context, [credit], action),
onUploadDocument: (BuildContext context, String path) {
final Completer<DocumentEntity> completer = Completer<DocumentEntity>();
final document = DocumentEntity().rebuild((b) => b
..invoiceId = credit.id
..path = path);
store.dispatch(
SaveDocumentRequest(document: document, completer: completer));
completer.future.then((client) {
Scaffold.of(context).showSnackBar(SnackBar(
content: SnackBarRow(
message: AppLocalization.of(context).uploadedDocument,
)));
}).catchError((Object error) {
showDialog<ErrorDialog>(
context: context,
builder: (BuildContext context) {
return ErrorDialog(error);
});
});
},
onDeleteDocument: (BuildContext context, DocumentEntity document) {
store.dispatch(DeleteDocumentRequest(
snackBarCompleter<Null>(
context, AppLocalization.of(context).deletedDocument),
[document.id]));
},
); );
} }
final AppState state;
final InvoiceEntity credit;
final CompanyEntity company;
final Function(BuildContext, EntityAction) onEntityAction;
final Function(BuildContext) onRefreshed;
final bool isSaving;
final bool isLoading;
final bool isDirty;
} }

View File

@ -223,8 +223,8 @@ class InvoiceEditDesktopState extends State<InvoiceEditDesktop>
validator: (String val) => val.trim().isEmpty validator: (String val) => val.trim().isEmpty
? AppLocalization.of(context).pleaseSelectADate ? AppLocalization.of(context).pleaseSelectADate
: null, : null,
labelText: widget.isQuote labelText: widget.entityType == EntityType.credit ? localization.creditDate :
? localization.quoteDate widget.entityType == EntityType.quote ? localization.quoteDate
: localization.invoiceDate, : localization.invoiceDate,
selectedDate: invoice.date, selectedDate: invoice.date,
onSelected: (date) { onSelected: (date) {

View File

@ -15,6 +15,7 @@ mixin LocalizationsProvider on LocaleCodeAware {
static final Map<String, Map<String, String>> _localizedValues = { static final Map<String, Map<String, String>> _localizedValues = {
'en': { 'en': {
// STARTER: lang key - do not remove comment // STARTER: lang key - do not remove comment
'credit_date': 'Credit Date',
'credit': 'Credit', 'credit': 'Credit',
'credits': 'Credits', 'credits': 'Credits',
'new_credit': 'New Credit', 'new_credit': 'New Credit',
@ -32772,15 +32773,19 @@ mixin LocalizationsProvider on LocaleCodeAware {
String get appUpdated => _localizedValues[localeCode]['app_updated']; String get appUpdated => _localizedValues[localeCode]['app_updated'];
// STARTER: lang field - do not remove comment // STARTER: lang field - do not remove comment
String get credit => _localizedValues[localeCode][' credit']; String get newCredit => _localizedValues[localeCode]['new_credit'];
String get credits => _localizedValues[localeCode][' credits'];
String get newCredit => _localizedValues[localeCode]['new_ credit']; String get createdCredit => _localizedValues[localeCode]['created_credit'];
String get createdCredit => _localizedValues[localeCode]['created_ credit'];
String get updatedCredit => _localizedValues[localeCode]['updated_ credit']; String get updatedCredit => _localizedValues[localeCode]['updated_credit'];
String get archivedCredit => _localizedValues[localeCode]['archived_ credit'];
String get deletedCredit => _localizedValues[localeCode]['deleted_ credit']; String get archivedCredit => _localizedValues[localeCode]['archived_credit'];
String get restoredCredit => _localizedValues[localeCode]['restored_ credit'];
String get editCredit => _localizedValues[localeCode]['edit_ credit']; String get deletedCredit => _localizedValues[localeCode]['deleted_credit'];
String get restoredCredit => _localizedValues[localeCode]['restored_credit'];
String get creditDate => _localizedValues[localeCode]['credit_date'];
String lookup(String key) { String lookup(String key) {
final lookupKey = toSnakeCase(key); final lookupKey = toSnakeCase(key);

View File

@ -431,7 +431,7 @@ else
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/utils/i18n.dart sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/utils/i18n.dart
comment="STARTER: lang field - do not remove comment" comment="STARTER: lang field - do not remove comment"
code="String get ${module_camel} => _localizedValues[localeCode][' ${module_snake}']; String get ${module_camel}s => _localizedValues[localeCode][' ${module_snake}s']; String get new${Module} => _localizedValues[localeCode]['new_ ${module_snake}']; String get created${Module} => _localizedValues[localeCode]['created_ ${module_snake}']; String get updated${Module} => _localizedValues[localeCode]['updated_ ${module_snake}']; String get archived${Module} => _localizedValues[localeCode]['archived_ ${module_snake}']; String get deleted${Module} => _localizedValues[localeCode]['deleted_ ${module_snake}']; String get restored${Module} => _localizedValues[localeCode]['restored_ ${module_snake}']; String get edit${Module} => _localizedValues[localeCode]['edit_ ${module_snake}'];${lineBreak}" code="String get ${module_camel} => _localizedValues[localeCode][' ${module_snake}']; String get ${module_camel}s => _localizedValues[localeCode]['${module_snake}s']; String get new${Module} => _localizedValues[localeCode]['new_${module_snake}']; String get created${Module} => _localizedValues[localeCode]['created_${module_snake}']; String get updated${Module} => _localizedValues[localeCode]['updated_${module_snake}']; String get archived${Module} => _localizedValues[localeCode]['archived_${module_snake}']; String get deleted${Module} => _localizedValues[localeCode]['deleted_${module_snake}']; String get restored${Module} => _localizedValues[localeCode]['restored_${module_snake}']; String get edit${Module} => _localizedValues[localeCode]['edit_${module_snake}'];${lineBreak}"
sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/utils/i18n.dart sed -i -e "s/$comment/$comment${lineBreak}$code/g" ./lib/utils/i18n.dart
echo "Generating built files.." echo "Generating built files.."