merge
This commit is contained in:
@@ -39,7 +39,7 @@ class _CargoTypeEditorState extends State<CargoTypeEditor> {
|
||||
_loadDefalut() {
|
||||
ShipmentRateModel shipmentRateModel =
|
||||
Provider.of<ShipmentRateModel>(context, listen: false);
|
||||
_cargo = shipmentRateModel.rate.defaultCargoType?.clone();
|
||||
_cargo = shipmentRateModel.rate.defaultCargoType.clone();
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -171,7 +171,7 @@ class PartSearchDelegate extends SearchDelegate<Carton> {
|
||||
// }
|
||||
|
||||
try {
|
||||
String barcode = await scanBarcode();
|
||||
String? barcode = await scanBarcode();
|
||||
if (barcode != null) {
|
||||
query = barcode;
|
||||
showResults(context);
|
||||
|
||||
@@ -103,10 +103,10 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
|
||||
_loadShipments() async {
|
||||
ShipmentModel shipmentModel =
|
||||
Provider.of<ShipmentModel>(context, listen: false);
|
||||
List<Shipment> shipments = await shipmentModel.getShipmentWithHandlingFee(
|
||||
List<Shipment?>? shipments = await shipmentModel.getShipmentWithHandlingFee(
|
||||
widget.fcsShipment!.id!, widget.customer!.id!);
|
||||
shipments.forEach((s) {
|
||||
s.isSelected = true;
|
||||
shipments!.forEach((s) {
|
||||
s!.isSelected = true;
|
||||
});
|
||||
setState(() {
|
||||
_invoice!.shipments = shipments;
|
||||
@@ -380,8 +380,8 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
|
||||
if (shipment == null) return;
|
||||
shipment.isSelected = true;
|
||||
setState(() {
|
||||
_invoice!.shipments.remove(shipment);
|
||||
_invoice!.shipments.add(shipment);
|
||||
_invoice!.shipments!.remove(shipment);
|
||||
_invoice!.shipments!.add(shipment);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -389,8 +389,8 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
|
||||
if (shipment == null) return;
|
||||
shipment.isSelected = false;
|
||||
setState(() {
|
||||
_invoice!.shipments.remove(shipment);
|
||||
_invoice!.shipments.add(shipment);
|
||||
_invoice!.shipments!.remove(shipment);
|
||||
_invoice!.shipments!.add(shipment);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -431,7 +431,7 @@ class _InvoiceEditorState extends State<InvoiceEditor> {
|
||||
invoice.handlingFee = _invoice!.getHandlingFee();
|
||||
invoice.cartons = _invoice!.cartons.where((c) => c.isChecked!).toList();
|
||||
invoice.shipments =
|
||||
_invoice!.shipments.where((s) => s.isSelected).toList();
|
||||
_invoice!.shipments!.where((s) => s!.isSelected).toList();
|
||||
invoice.discount = _invoice!.discount;
|
||||
invoice.deliveryFee = _invoice!.deliveryFee;
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ typedef OnAdd(Shipment shipment);
|
||||
typedef OnRemove(Shipment shipment);
|
||||
|
||||
class InvoiceHandlingFeeList extends StatelessWidget {
|
||||
final List<Shipment>? shipments;
|
||||
final List<Shipment?>? shipments;
|
||||
final OnAdd? onAdd;
|
||||
final OnRemove? onRemove;
|
||||
|
||||
@@ -72,7 +72,7 @@ class InvoiceHandlingFeeList extends StatelessWidget {
|
||||
onSelectChanged: (value) => Navigator.pop(context, c),
|
||||
cells: [
|
||||
MyDataCell(new Text(
|
||||
c.shipmentNumber!,
|
||||
c!.shipmentNumber!,
|
||||
style: textStyle,
|
||||
)),
|
||||
MyDataCell(
|
||||
|
||||
@@ -39,8 +39,8 @@ class _InvoiceInfoState extends State<InvoiceInfo> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
_invoice = widget.invoice!;
|
||||
_invoice!.shipments.forEach((s) {
|
||||
s.isSelected = true;
|
||||
_invoice!.shipments!.forEach((s) {
|
||||
s!.isSelected = true;
|
||||
});
|
||||
_loadCartons();
|
||||
}
|
||||
|
||||
@@ -70,11 +70,11 @@ class InvoiceTable extends StatelessWidget {
|
||||
"${c.calWeight.toStringAsFixed(2)} x ${c.calRate.toStringAsFixed(2)}",
|
||||
amount: "${c.calAmount.toStringAsFixed(2)}"));
|
||||
});
|
||||
invoice!.shipments.where((ss) => (ss.isSelected )).forEach((s) {
|
||||
invoice!.shipments!.where((ss) => (ss!.isSelected )).forEach((s) {
|
||||
tableRows.add(InvoiceTableRow(
|
||||
data: s,
|
||||
invoiceDataType: InvoiceDataType.HandlingFeeType,
|
||||
desc: "Handling fee\n${s.shipmentNumber}",
|
||||
desc: "Handling fee\n${s!.shipmentNumber}",
|
||||
rate: "",
|
||||
amount: "${s.handlingFee.toStringAsFixed(2)}"));
|
||||
});
|
||||
|
||||
@@ -260,7 +260,7 @@ class PackageModel extends BaseModel {
|
||||
}
|
||||
|
||||
Future<void> createReceiving(
|
||||
User user, Package package, List<File> files) async {
|
||||
User user, Package package, List<File?> files) async {
|
||||
if (user != null) {
|
||||
package.fcsID = user.fcsID;
|
||||
}
|
||||
@@ -288,22 +288,21 @@ class PackageModel extends BaseModel {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateReceiving(User user, Package package, List<File> files,
|
||||
List<String> deletedUrls) async {
|
||||
Future<void> updateReceiving(User user, Package package, List<File?> files,
|
||||
List<String?> deletedUrls) async {
|
||||
if (user != null) {
|
||||
package.fcsID = user.fcsID;
|
||||
}
|
||||
if (deletedUrls != null) {
|
||||
for (String url in deletedUrls) {
|
||||
for (String? url in deletedUrls) {
|
||||
package.photoUrls.remove(url);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> uploadedURL = [];
|
||||
if (files != null) {
|
||||
var count = (package.photoUrls?.length ?? 0) +
|
||||
files.length -
|
||||
(deletedUrls?.length ?? 0);
|
||||
var count =
|
||||
(package.photoUrls.length) + files.length - (deletedUrls.length);
|
||||
|
||||
if (count > uploadPhotoLimit)
|
||||
throw Exception("Exceed number of file upload");
|
||||
@@ -333,18 +332,17 @@ class PackageModel extends BaseModel {
|
||||
}
|
||||
|
||||
Future<void> updateProcessing(
|
||||
Package package, List<File> files, List<String> deletedUrls) async {
|
||||
Package package, List<File?> files, List<String?> deletedUrls) async {
|
||||
if (deletedUrls != null) {
|
||||
for (String url in deletedUrls) {
|
||||
for (String? url in deletedUrls) {
|
||||
package.photoUrls.remove(url);
|
||||
}
|
||||
}
|
||||
|
||||
List<String> uploadedURL = [];
|
||||
if (files != null) {
|
||||
var count = (package.photoUrls?.length ?? 0) +
|
||||
files.length -
|
||||
(deletedUrls?.length ?? 0);
|
||||
var count =
|
||||
(package.photoUrls.length) + files.length - (deletedUrls.length);
|
||||
|
||||
if (count > uploadPhotoLimit)
|
||||
throw Exception("Exceed number of file upload");
|
||||
|
||||
@@ -164,7 +164,7 @@ class _TrackingIDPageState extends State<TrackingIDPage> {
|
||||
// }
|
||||
|
||||
try {
|
||||
String barcode = await scanBarcode();
|
||||
String? barcode = await scanBarcode();
|
||||
if (barcode != null) {
|
||||
setState(() {
|
||||
_transcationIDCtl.text = barcode;
|
||||
|
||||
@@ -147,7 +147,7 @@ class PackageSearchDelegate extends SearchDelegate<Package> {
|
||||
// Barcode bc = barcodes.firstWhere((element) => true);
|
||||
// String barcode;
|
||||
// if (bc != null) barcode = bc.rawValue;
|
||||
String barcode = await scanBarcode();
|
||||
String? barcode = await scanBarcode();
|
||||
if (barcode != null) {
|
||||
query = barcode;
|
||||
showResults(context);
|
||||
|
||||
@@ -80,7 +80,7 @@ class _ProfileState extends State<Profile> {
|
||||
);
|
||||
|
||||
final phonenumberbox = DisplayText(
|
||||
text: mainModel.user!.phone ?? "",
|
||||
text: mainModel.user!.phone,
|
||||
labelTextKey: "profile.phone",
|
||||
iconData: Icons.phone,
|
||||
);
|
||||
|
||||
@@ -36,7 +36,7 @@ class _CustomEditorState extends State<CustomEditor> {
|
||||
_productController.text = _custom.name??"";
|
||||
_feeController.text = _custom.customDutyFee.toStringAsFixed(2);
|
||||
_shipmentRateController.text =
|
||||
_custom.rate == null ? "" : _custom.rate?.toStringAsFixed(2) ?? '';
|
||||
_custom.rate == null ? "" : _custom.rate.toStringAsFixed(2);
|
||||
} else {
|
||||
_isNew = true;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class _CustomListState extends State<CustomList> {
|
||||
custom.rate == null
|
||||
? ""
|
||||
: "Shipment rate \$ " +
|
||||
custom.rate!.toStringAsFixed(2)),
|
||||
custom.rate.toStringAsFixed(2)),
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
||||
@@ -62,11 +62,11 @@ class _ShipmentRatesCalState extends State<ShipmentRatesCal> {
|
||||
var amount = box.calAmount(rate);
|
||||
var shipmentWeight = box.getShipmentWeight(rate.volumetricRatio);
|
||||
var effectiveWeight =
|
||||
_cargoType.weight! > shipmentWeight ? _cargoType.weight : shipmentWeight;
|
||||
_cargoType.weight > shipmentWeight ? _cargoType.weight : shipmentWeight;
|
||||
|
||||
setState(() {
|
||||
_deliveryFee =
|
||||
effectiveWeight! > rate.freeDeliveryWeight ? 0 : rate.deliveryFee;
|
||||
effectiveWeight > rate.freeDeliveryWeight ? 0 : rate.deliveryFee;
|
||||
_amount = amount == null ? 0 : amount + _deliveryFee;
|
||||
_shipmentWeight = shipmentWeight.toDouble();
|
||||
});
|
||||
|
||||
@@ -212,7 +212,7 @@ class _ReceivingEditorState extends State<ReceivingEditor> {
|
||||
// }
|
||||
|
||||
try {
|
||||
String barcode = await scanBarcode();
|
||||
String? barcode = await scanBarcode();
|
||||
if (barcode != null) {
|
||||
setState(() {
|
||||
_trackingIDCtl.text = barcode;
|
||||
|
||||
@@ -56,7 +56,7 @@ class _ShipmentAssignState extends State<ShipmentAssign> {
|
||||
_selectedShipmentType = _shipment!.shipmentType;
|
||||
_fromTimeEditingController.text = _shipment!.pickupTimeStart!;
|
||||
_toTimeEditingController.text = _shipment!.pickupTimeEnd!;
|
||||
_pickupDate.text = dateFormatter.format(_shipment!.pickupDate! ?? now);
|
||||
_pickupDate.text = dateFormatter.format(_shipment!.pickupDate ?? now);
|
||||
_handlingFee.text = _shipment!.handlingFee != null
|
||||
? _shipment!.handlingFee.toString()
|
||||
: "0";
|
||||
|
||||
@@ -37,7 +37,7 @@ class _ShipmentConfirmState extends State<ShipmentConfirm> {
|
||||
super.initState();
|
||||
|
||||
_shipment = widget.shipment;
|
||||
_handlingFee.text = _shipment!.handlingFee?.toString() ?? "0";
|
||||
_handlingFee.text = _shipment!.handlingFee.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -223,7 +223,7 @@ class _ShipmentInfoState extends State<ShipmentInfo> {
|
||||
iconData: MaterialCommunityIcons.worker);
|
||||
var handlingFeeBox = DisplayText(
|
||||
labelTextKey: "shipment.handling.fee",
|
||||
text: (_shipment!.handlingFee ?? 0).toString(),
|
||||
text: (_shipment!.handlingFee).toString(),
|
||||
iconData: FontAwesome.truck);
|
||||
|
||||
final assignCompleteBtn = LocalButton(
|
||||
|
||||
@@ -8,27 +8,28 @@ import 'package:fcs/pages/widgets/local_text.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_icons_null_safety/flutter_icons_null_safety.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:zefyr/zefyr.dart';
|
||||
// import 'package:zefyr/zefyr.dart';
|
||||
|
||||
typedef void ProfileCallback();
|
||||
|
||||
class TermEdit extends StatefulWidget {
|
||||
final Term term;
|
||||
TermEdit({this.term});
|
||||
TermEdit({required this.term});
|
||||
@override
|
||||
_TermEditState createState() => _TermEditState();
|
||||
}
|
||||
|
||||
class _TermEditState extends State<TermEdit> {
|
||||
/// Allows to control the editor and the document.
|
||||
ZefyrController _controllerEng;
|
||||
ZefyrController _controllerMm;
|
||||
// ZefyrController _controllerEng;
|
||||
// ZefyrController _controllerMm;
|
||||
|
||||
/// Zefyr editor like any other input field requires a focus node.
|
||||
FocusNode _focusNodeEng;
|
||||
FocusNode _focusNodeMm;
|
||||
bool _isLoading;
|
||||
// FocusNode _focusNodeEng;
|
||||
// FocusNode _focusNodeMm;
|
||||
bool _isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -36,23 +37,23 @@ class _TermEditState extends State<TermEdit> {
|
||||
_isLoading = false;
|
||||
|
||||
// Here we must load the document and pass it to Zefyr controller.
|
||||
_controllerEng = ZefyrController(_loadDocument(widget.term.termEng));
|
||||
_controllerMm = ZefyrController(_loadDocument(widget.term.termMm));
|
||||
_focusNodeEng = FocusNode();
|
||||
_focusNodeMm = FocusNode();
|
||||
// _controllerEng = ZefyrController(_loadDocument(widget.term.termEng));
|
||||
// _controllerMm = ZefyrController(_loadDocument(widget.term.termMm));
|
||||
// _focusNodeEng = FocusNode();
|
||||
// _focusNodeMm = FocusNode();
|
||||
}
|
||||
|
||||
/// Loads the document to be edited in Zefyr.
|
||||
NotusDocument _loadDocument(String data) {
|
||||
NotusDocument doc;
|
||||
try {
|
||||
doc = NotusDocument.fromJson(jsonDecode(data));
|
||||
} catch (e) {}
|
||||
if (doc == null) {
|
||||
doc = NotusDocument();
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
// NotusDocument _loadDocument(String data) {
|
||||
// NotusDocument doc;
|
||||
// try {
|
||||
// doc = NotusDocument.fromJson(jsonDecode(data));
|
||||
// } catch (e) {}
|
||||
// if (doc == null) {
|
||||
// doc = NotusDocument();
|
||||
// }
|
||||
// return doc;
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -115,8 +116,8 @@ class _TermEditState extends State<TermEdit> {
|
||||
height: MediaQuery.of(context).size.height - 200,
|
||||
child: TabBarView(
|
||||
children: [
|
||||
textEditor(_controllerEng, _focusNodeEng),
|
||||
textEditor(_controllerMm, _focusNodeMm),
|
||||
// textEditor(_controllerEng, _focusNodeEng),
|
||||
// textEditor(_controllerMm, _focusNodeMm),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -128,35 +129,35 @@ class _TermEditState extends State<TermEdit> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget textEditor(ZefyrController controller, FocusNode focusNode) {
|
||||
return ListView(
|
||||
children: [
|
||||
Container(
|
||||
height: MediaQuery.of(context).size.height - 200,
|
||||
child: ZefyrScaffold(
|
||||
child: ZefyrTheme(
|
||||
data: ZefyrThemeData().copyWith(
|
||||
defaultLineTheme: LineTheme(
|
||||
padding: EdgeInsets.all(0),
|
||||
textStyle: TextStyle(fontFamily: "Myanmar3"),
|
||||
),
|
||||
),
|
||||
child: ZefyrEditor(
|
||||
autofocus: false,
|
||||
padding: EdgeInsets.all(16),
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// savebtn,
|
||||
SizedBox(
|
||||
height: 10,
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
// Widget textEditor(ZefyrController controller, FocusNode focusNode) {
|
||||
// return ListView(
|
||||
// children: [
|
||||
// Container(
|
||||
// height: MediaQuery.of(context).size.height - 200,
|
||||
// child: ZefyrScaffold(
|
||||
// child: ZefyrTheme(
|
||||
// data: ZefyrThemeData().copyWith(
|
||||
// defaultLineTheme: LineTheme(
|
||||
// padding: EdgeInsets.all(0),
|
||||
// textStyle: TextStyle(fontFamily: "Myanmar3"),
|
||||
// ),
|
||||
// ),
|
||||
// child: ZefyrEditor(
|
||||
// autofocus: false,
|
||||
// padding: EdgeInsets.all(16),
|
||||
// controller: controller,
|
||||
// focusNode: focusNode,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// // savebtn,
|
||||
// SizedBox(
|
||||
// height: 10,
|
||||
// )
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
|
||||
_unfocus() {
|
||||
FocusScope.of(context).unfocus();
|
||||
@@ -167,11 +168,11 @@ class _TermEditState extends State<TermEdit> {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
final contentsEng = jsonEncode(_controllerEng.document);
|
||||
final contentsMm = jsonEncode(_controllerMm.document);
|
||||
print('contents => $contentsEng');
|
||||
TermModel termModel = Provider.of<TermModel>(context, listen: false);
|
||||
await termModel.saveTerm(Term(termEng: contentsEng, termMm: contentsMm));
|
||||
// final contentsEng = jsonEncode(_controllerEng.document);
|
||||
// final contentsMm = jsonEncode(_controllerMm.document);
|
||||
// print('contents => $contentsEng');
|
||||
// TermModel termModel = Provider.of<TermModel>(context, listen: false);
|
||||
// await termModel.saveTerm(Term(termEng: contentsEng, termMm: contentsMm));
|
||||
} catch (e) {
|
||||
showMsgDialog(context, "Error", e.toString());
|
||||
} finally {
|
||||
|
||||
@@ -10,46 +10,46 @@ import 'package:fcs/pages/widgets/local_text.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:zefyr/zefyr.dart';
|
||||
// import 'package:zefyr/zefyr.dart';
|
||||
|
||||
typedef void ProfileCallback();
|
||||
|
||||
class TermPage extends StatefulWidget {
|
||||
const TermPage({
|
||||
Key key,
|
||||
Key? key,
|
||||
}) : super(key: key);
|
||||
@override
|
||||
_TermPageState createState() => _TermPageState();
|
||||
}
|
||||
|
||||
class _TermPageState extends State<TermPage> {
|
||||
ZefyrController _controller;
|
||||
FocusNode _focusNode;
|
||||
NotusDocument document = new NotusDocument();
|
||||
// ZefyrController _controller;
|
||||
// FocusNode _focusNode;
|
||||
// NotusDocument document = new NotusDocument();
|
||||
bool isLoading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_focusNode = FocusNode();
|
||||
// _focusNode = FocusNode();
|
||||
}
|
||||
|
||||
NotusDocument _loadDocument(Setting setting) {
|
||||
bool isEng = Provider.of<LanguageModel>(context).isEng;
|
||||
String term = isEng ? setting.termsEng : setting.termsMm;
|
||||
NotusDocument doc;
|
||||
try {
|
||||
doc = NotusDocument.fromJson(jsonDecode(term));
|
||||
} catch (e) {}
|
||||
if (doc == null) {
|
||||
doc = NotusDocument();
|
||||
}
|
||||
return doc;
|
||||
}
|
||||
// NotusDocument _loadDocument(Setting setting) {
|
||||
// bool isEng = Provider.of<LanguageModel>(context).isEng;
|
||||
// String term = isEng ? setting.termsEng : setting.termsMm;
|
||||
// NotusDocument doc;
|
||||
// try {
|
||||
// doc = NotusDocument.fromJson(jsonDecode(term));
|
||||
// } catch (e) {}
|
||||
// if (doc == null) {
|
||||
// doc = NotusDocument();
|
||||
// }
|
||||
// return doc;
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Setting setting = Provider.of<MainModel>(context).setting;
|
||||
Setting? setting = Provider.of<MainModel>(context).setting;
|
||||
bool isEditable = context.select((MainModel m) => m.termEditable());
|
||||
|
||||
return Scaffold(
|
||||
@@ -76,7 +76,7 @@ class _TermPageState extends State<TermPage> {
|
||||
onPressed: () =>
|
||||
Navigator.of(context).push<void>(CupertinoPageRoute(
|
||||
builder: (context) =>
|
||||
TermEdit(term: Term.fromSetting(setting)),
|
||||
TermEdit(term: Term.fromSetting(setting!)),
|
||||
)),
|
||||
icon: Icon(
|
||||
CupertinoIcons.pen,
|
||||
@@ -85,25 +85,25 @@ class _TermPageState extends State<TermPage> {
|
||||
]
|
||||
: [],
|
||||
),
|
||||
body: ZefyrTheme(
|
||||
data: ZefyrThemeData().copyWith(
|
||||
defaultLineTheme: LineTheme(
|
||||
padding: EdgeInsets.all(0),
|
||||
textStyle: TextStyle(fontFamily: "Myanmar3"),
|
||||
),
|
||||
),
|
||||
// data: ZefyrThemeData().copyWith(
|
||||
// defaultLineTheme: LineTheme(
|
||||
// textStyle: TextStyle(color: Colors.black),
|
||||
// padding: EdgeInsets.all(0))),
|
||||
child: ZefyrScaffold(
|
||||
child: ZefyrEditor(
|
||||
mode: ZefyrMode.view,
|
||||
padding: EdgeInsets.all(16),
|
||||
controller: ZefyrController(_loadDocument(setting)),
|
||||
focusNode: _focusNode,
|
||||
),
|
||||
)),
|
||||
// body: ZefyrTheme(
|
||||
// data: ZefyrThemeData().copyWith(
|
||||
// defaultLineTheme: LineTheme(
|
||||
// padding: EdgeInsets.all(0),
|
||||
// textStyle: TextStyle(fontFamily: "Myanmar3"),
|
||||
// ),
|
||||
// ),
|
||||
// // data: ZefyrThemeData().copyWith(
|
||||
// // defaultLineTheme: LineTheme(
|
||||
// // textStyle: TextStyle(color: Colors.black),
|
||||
// // padding: EdgeInsets.all(0))),
|
||||
// child: ZefyrScaffold(
|
||||
// child: ZefyrEditor(
|
||||
// mode: ZefyrMode.view,
|
||||
// padding: EdgeInsets.all(16),
|
||||
// controller: ZefyrController(_loadDocument(setting)),
|
||||
// focusNode: _focusNode,
|
||||
// ),
|
||||
// )),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,12 +83,16 @@ class MyDataRow {
|
||||
///
|
||||
/// The [cells] argument must not be null.
|
||||
MyDataRow.byIndex({
|
||||
<<<<<<< HEAD
|
||||
int index = 0,
|
||||
=======
|
||||
int? index,
|
||||
>>>>>>> upstream/master
|
||||
this.selected = false,
|
||||
this.onSelectChanged,
|
||||
required this.cells,
|
||||
}) : assert(cells != null),
|
||||
key = ValueKey<int>(index);
|
||||
key = ValueKey<int>(index!);
|
||||
|
||||
/// A [Key] that uniquely identifies this row. This is used to
|
||||
/// ensure that if a row is added or removed, any stateful widgets
|
||||
@@ -320,7 +324,7 @@ class MyDataTable extends StatelessWidget {
|
||||
this.columnSpacing = 56.0,
|
||||
this.oddLine,
|
||||
this.evenLine,
|
||||
@required this.rows,
|
||||
required this.rows,
|
||||
}) : assert(columns != null),
|
||||
assert(columns.isNotEmpty),
|
||||
assert(sortColumnIndex == null ||
|
||||
@@ -451,10 +455,10 @@ class MyDataTable extends StatelessWidget {
|
||||
Color(0x1E000000); // Dark theme variant is just a guess.
|
||||
|
||||
Widget _buildCheckbox({
|
||||
Color color,
|
||||
bool checked,
|
||||
VoidCallback onRowTap,
|
||||
ValueChanged<bool> onCheckboxChanged,
|
||||
Color? color,
|
||||
bool? checked,
|
||||
VoidCallback? onRowTap,
|
||||
ValueChanged<bool>? onCheckboxChanged,
|
||||
}) {
|
||||
Widget contents = Semantics(
|
||||
container: true,
|
||||
@@ -465,7 +469,9 @@ class MyDataTable extends StatelessWidget {
|
||||
child: Checkbox(
|
||||
activeColor: color,
|
||||
value: checked,
|
||||
onChanged: onCheckboxChanged,
|
||||
onChanged: (bool? value) {
|
||||
onCheckboxChanged!(value ?? false);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -483,32 +489,33 @@ class MyDataTable extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildHeadingCell({
|
||||
BuildContext context,
|
||||
EdgeInsetsGeometry padding,
|
||||
Widget label,
|
||||
String tooltip,
|
||||
bool numeric,
|
||||
VoidCallback onSort,
|
||||
bool sorted,
|
||||
bool ascending,
|
||||
required BuildContext context,
|
||||
EdgeInsetsGeometry? padding,
|
||||
Widget? label,
|
||||
String? tooltip,
|
||||
bool? numeric,
|
||||
VoidCallback? onSort,
|
||||
bool? sorted,
|
||||
bool? ascending,
|
||||
}) {
|
||||
if (onSort != null) {
|
||||
final Widget arrow = _SortArrow(
|
||||
visible: sorted,
|
||||
visible: sorted!,
|
||||
down: sorted ? ascending : null,
|
||||
duration: _sortArrowAnimationDuration,
|
||||
);
|
||||
const Widget arrowPadding = SizedBox(width: _sortArrowPadding);
|
||||
label = Row(
|
||||
textDirection: numeric ? TextDirection.rtl : null,
|
||||
children: <Widget>[label, arrowPadding, arrow],
|
||||
textDirection: (numeric ?? false) ? TextDirection.rtl : null,
|
||||
children: <Widget>[label ?? Container(), arrowPadding, arrow],
|
||||
);
|
||||
}
|
||||
label = Container(
|
||||
padding: padding,
|
||||
height: headingRowHeight,
|
||||
alignment:
|
||||
numeric ? Alignment.centerRight : AlignmentDirectional.centerStart,
|
||||
alignment: (numeric ?? false)
|
||||
? Alignment.centerRight
|
||||
: AlignmentDirectional.centerStart,
|
||||
child: AnimatedDefaultTextStyle(
|
||||
style: TextStyle(
|
||||
// TODO(ianh): font family should match Theme; see https://github.com/flutter/flutter/issues/3116
|
||||
@@ -516,12 +523,16 @@ class MyDataTable extends StatelessWidget {
|
||||
fontSize: _headingFontSize,
|
||||
height: math.min(1.0, headingRowHeight / _headingFontSize),
|
||||
color: (Theme.of(context).brightness == Brightness.light)
|
||||
? ((onSort != null && sorted) ? Colors.black87 : Colors.black54)
|
||||
: ((onSort != null && sorted) ? Colors.white : Colors.white70),
|
||||
? ((onSort != null && (sorted ?? false))
|
||||
? Colors.black87
|
||||
: Colors.black54)
|
||||
: ((onSort != null && (sorted ?? false))
|
||||
? Colors.white
|
||||
: Colors.white70),
|
||||
),
|
||||
softWrap: false,
|
||||
duration: _sortArrowAnimationDuration,
|
||||
child: label,
|
||||
child: label ?? Container(),
|
||||
),
|
||||
);
|
||||
if (tooltip != null) {
|
||||
@@ -540,42 +551,43 @@ class MyDataTable extends StatelessWidget {
|
||||
}
|
||||
|
||||
Widget _buildMyDataCell({
|
||||
BuildContext context,
|
||||
EdgeInsetsGeometry padding,
|
||||
Widget label,
|
||||
bool numeric,
|
||||
bool placeholder,
|
||||
bool showEditIcon,
|
||||
VoidCallback onTap,
|
||||
VoidCallback onSelectChanged,
|
||||
required BuildContext context,
|
||||
EdgeInsetsGeometry? padding,
|
||||
Widget? label,
|
||||
bool? numeric,
|
||||
bool? placeholder,
|
||||
bool? showEditIcon,
|
||||
VoidCallback? onTap,
|
||||
VoidCallback? onSelectChanged,
|
||||
}) {
|
||||
final bool isLightTheme = Theme.of(context).brightness == Brightness.light;
|
||||
if (showEditIcon) {
|
||||
if (showEditIcon ?? false) {
|
||||
const Widget icon = Icon(Icons.edit, size: 18.0);
|
||||
label = Expanded(child: label);
|
||||
label = Expanded(child: label ?? Container());
|
||||
label = Row(
|
||||
textDirection: numeric ? TextDirection.rtl : null,
|
||||
textDirection: (numeric ?? false) ? TextDirection.rtl : null,
|
||||
children: <Widget>[label, icon],
|
||||
);
|
||||
}
|
||||
label = Container(
|
||||
padding: padding,
|
||||
height: MyDataRowHeight,
|
||||
alignment:
|
||||
numeric ? Alignment.centerRight : AlignmentDirectional.centerStart,
|
||||
alignment: (numeric ?? false)
|
||||
? Alignment.centerRight
|
||||
: AlignmentDirectional.centerStart,
|
||||
child: DefaultTextStyle(
|
||||
style: TextStyle(
|
||||
// TODO(ianh): font family should be Roboto; see https://github.com/flutter/flutter/issues/3116
|
||||
fontSize: 13.0,
|
||||
color: isLightTheme
|
||||
? (placeholder ? Colors.black38 : Colors.black87)
|
||||
: (placeholder ? Colors.white38 : Colors.white70),
|
||||
? ((placeholder ?? false) ? Colors.black38 : Colors.black87)
|
||||
: ((placeholder ?? false) ? Colors.white38 : Colors.white70),
|
||||
),
|
||||
child: IconTheme.merge(
|
||||
data: IconThemeData(
|
||||
color: isLightTheme ? Colors.black54 : Colors.white70,
|
||||
),
|
||||
child: DropdownButtonHideUnderline(child: label),
|
||||
child: DropdownButtonHideUnderline(child: label ?? Container()),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -614,6 +626,10 @@ class MyDataTable extends StatelessWidget {
|
||||
|
||||
final List<TableColumnWidth> tableColumns = (columns.length +
|
||||
(showCheckboxColumn ? 1 : 0)) as List<TableColumnWidth>;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
>>>>>>> upstream/master
|
||||
final List<TableRow> tableRows = List<TableRow>.generate(
|
||||
rows.length + 1, // the +1 is for the header row
|
||||
(int index) {
|
||||
@@ -626,36 +642,36 @@ class MyDataTable extends StatelessWidget {
|
||||
: index.isEven && evenLine != null
|
||||
? evenLine
|
||||
: _kUnselectedDecoration,
|
||||
children: List<Widget>(tableColumns.length),
|
||||
children: tableColumns.map((e) => Container()).toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
int rowIndex;
|
||||
|
||||
int displayColumnIndex = 0;
|
||||
if (showCheckboxColumn) {
|
||||
tableColumns[0] = FixedColumnWidth(
|
||||
horizontalMargin + Checkbox.width + horizontalMargin / 2.0);
|
||||
tableRows[0].children[0] = _buildCheckbox(
|
||||
color: theme.accentColor,
|
||||
checked: allChecked,
|
||||
onCheckboxChanged: _handleSelectAll,
|
||||
);
|
||||
rowIndex = 1;
|
||||
for (MyDataRow row in rows) {
|
||||
tableRows[rowIndex].children[0] = _buildCheckbox(
|
||||
color: theme.accentColor,
|
||||
checked: row.selected,
|
||||
onRowTap: () => row.onSelectChanged != null
|
||||
? row.onSelectChanged(!row.selected)
|
||||
: null,
|
||||
onCheckboxChanged: row.onSelectChanged,
|
||||
);
|
||||
rowIndex += 1;
|
||||
}
|
||||
displayColumnIndex += 1;
|
||||
}
|
||||
int displayColumnIndex = 0;
|
||||
// if (showCheckboxColumn) {
|
||||
// tableColumns[0] = FixedColumnWidth(
|
||||
// horizontalMargin + Checkbox.width + horizontalMargin / 2.0);
|
||||
// tableRows[0].children![0] = _buildCheckbox(
|
||||
// color: theme.accentColor,
|
||||
// checked: allChecked,
|
||||
// onCheckboxChanged: _handleSelectAll,
|
||||
// );
|
||||
// rowIndex = 1;
|
||||
// for (MyDataRow row in rows) {
|
||||
// tableRows[rowIndex].children[0] = _buildCheckbox(
|
||||
// color: theme.accentColor,
|
||||
// checked: row.selected,
|
||||
// onRowTap: () => row.onSelectChanged != null
|
||||
// ? row.onSelectChanged(!row.selected)
|
||||
// : null,
|
||||
// onCheckboxChanged: row.onSelectChanged,
|
||||
// );
|
||||
// rowIndex += 1;
|
||||
// }
|
||||
// displayColumnIndex += 1;
|
||||
// }
|
||||
|
||||
for (int MyDataColumnIndex = 0;
|
||||
MyDataColumnIndex < columns.length;
|
||||
@@ -688,14 +704,14 @@ class MyDataTable extends StatelessWidget {
|
||||
} else {
|
||||
tableColumns[displayColumnIndex] = const IntrinsicColumnWidth();
|
||||
}
|
||||
tableRows[0].children[displayColumnIndex] = _buildHeadingCell(
|
||||
tableRows[0].children![displayColumnIndex] = _buildHeadingCell(
|
||||
context: context,
|
||||
padding: padding,
|
||||
label: column.label,
|
||||
tooltip: column.tooltip,
|
||||
numeric: column.numeric,
|
||||
onSort: () => column.onSort != null
|
||||
? column.onSort(MyDataColumnIndex,
|
||||
? column.onSort!(MyDataColumnIndex,
|
||||
sortColumnIndex != MyDataColumnIndex || !sortAscending)
|
||||
: null,
|
||||
sorted: MyDataColumnIndex == sortColumnIndex,
|
||||
@@ -704,7 +720,7 @@ class MyDataTable extends StatelessWidget {
|
||||
rowIndex = 1;
|
||||
for (MyDataRow row in rows) {
|
||||
final MyDataCell cell = row.cells[MyDataColumnIndex];
|
||||
tableRows[rowIndex].children[displayColumnIndex] = _buildMyDataCell(
|
||||
tableRows[rowIndex].children?[displayColumnIndex] = _buildMyDataCell(
|
||||
context: context,
|
||||
padding: padding,
|
||||
label: cell.child,
|
||||
@@ -713,7 +729,7 @@ class MyDataTable extends StatelessWidget {
|
||||
showEditIcon: cell.showEditIcon,
|
||||
onTap: cell.onTap,
|
||||
onSelectChanged: () => row.onSelectChanged != null
|
||||
? row.onSelectChanged(!row.selected)
|
||||
? row.onSelectChanged!(!row.selected)
|
||||
: null,
|
||||
);
|
||||
rowIndex += 1;
|
||||
@@ -745,11 +761,19 @@ class TableRowInkWell extends InkResponse {
|
||||
/// Creates an ink well for a table row.
|
||||
const TableRowInkWell({
|
||||
Key? key,
|
||||
<<<<<<< HEAD
|
||||
Widget child,
|
||||
GestureTapCallback onTap,
|
||||
GestureTapCallback onDoubleTap,
|
||||
GestureLongPressCallback onLongPress,
|
||||
ValueChanged<bool> onHighlightChanged,
|
||||
=======
|
||||
Widget? child,
|
||||
GestureTapCallback? onTap,
|
||||
GestureTapCallback? onDoubleTap,
|
||||
GestureLongPressCallback? onLongPress,
|
||||
ValueChanged<bool>? onHighlightChanged,
|
||||
>>>>>>> upstream/master
|
||||
}) : super(
|
||||
key: key,
|
||||
child: child,
|
||||
@@ -765,7 +789,7 @@ class TableRowInkWell extends InkResponse {
|
||||
RectCallback getRectCallback(RenderBox referenceBox) {
|
||||
return () {
|
||||
RenderObject cell = referenceBox;
|
||||
AbstractNode table = cell.parent;
|
||||
AbstractNode? table = cell.parent;
|
||||
final Matrix4 transform = Matrix4.identity();
|
||||
while (table is RenderObject && table is! RenderTable) {
|
||||
final RenderObject parentBox = table as RenderObject;
|
||||
@@ -778,11 +802,11 @@ class TableRowInkWell extends InkResponse {
|
||||
final TableCellParentData cellParentData =
|
||||
cell.parentData as TableCellParentData;
|
||||
assert(cellParentData.y != null);
|
||||
final Rect rect = table.getRowBox(cellParentData.y);
|
||||
final Rect rect = table.getRowBox(cellParentData.y!);
|
||||
// The rect is in the table's coordinate space. We need to change it to the
|
||||
// TableRowInkWell's coordinate space.
|
||||
table.applyPaintTransform(cell, transform);
|
||||
final Offset offset = MatrixUtils.getAsTranslation(transform);
|
||||
final Offset? offset = MatrixUtils.getAsTranslation(transform);
|
||||
if (offset != null) return rect.shift(-offset);
|
||||
}
|
||||
return Rect.zero;
|
||||
@@ -804,17 +828,18 @@ class _SortArrow extends StatefulWidget {
|
||||
this.duration,
|
||||
}) : super(key: key);
|
||||
|
||||
final bool visible;
|
||||
final bool? visible;
|
||||
|
||||
final bool down;
|
||||
final bool? down;
|
||||
|
||||
final Duration duration;
|
||||
final Duration? duration;
|
||||
|
||||
@override
|
||||
_SortArrowState createState() => _SortArrowState();
|
||||
}
|
||||
|
||||
class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
|
||||
<<<<<<< HEAD
|
||||
late AnimationController _opacityController;
|
||||
late Animation<double> _opacityAnimation;
|
||||
|
||||
@@ -823,6 +848,16 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
|
||||
double _orientationOffset = 0.0;
|
||||
|
||||
late bool _down;
|
||||
=======
|
||||
AnimationController? _opacityController;
|
||||
Animation<double>? _opacityAnimation;
|
||||
|
||||
AnimationController? _orientationController;
|
||||
Animation<double>? _orientationAnimation;
|
||||
double _orientationOffset = 0.0;
|
||||
|
||||
bool? _down;
|
||||
>>>>>>> upstream/master
|
||||
|
||||
static final Animatable<double> _turnTween =
|
||||
Tween<double>(begin: 0.0, end: math.pi)
|
||||
@@ -838,15 +873,16 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
|
||||
),
|
||||
curve: Curves.fastOutSlowIn,
|
||||
)..addListener(_rebuild);
|
||||
_opacityController.value = widget.visible ? 1.0 : 0.0;
|
||||
_opacityController!.value = (widget.visible ?? false) ? 1.0 : 0.0;
|
||||
_orientationController = AnimationController(
|
||||
duration: widget.duration,
|
||||
vsync: this,
|
||||
);
|
||||
_orientationAnimation = _orientationController.drive(_turnTween)
|
||||
_orientationAnimation = _orientationController!.drive(_turnTween)
|
||||
..addListener(_rebuild)
|
||||
..addStatusListener(_resetOrientationAnimation);
|
||||
if (widget.visible) _orientationOffset = widget.down ? 0.0 : math.pi;
|
||||
if (widget.visible ?? false)
|
||||
_orientationOffset = (widget.down ?? false) ? 0.0 : math.pi;
|
||||
}
|
||||
|
||||
void _rebuild() {
|
||||
@@ -857,9 +893,9 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
|
||||
|
||||
void _resetOrientationAnimation(AnimationStatus status) {
|
||||
if (status == AnimationStatus.completed) {
|
||||
assert(_orientationAnimation.value == math.pi);
|
||||
assert(_orientationAnimation!.value == math.pi);
|
||||
_orientationOffset += math.pi;
|
||||
_orientationController.value =
|
||||
_orientationController!.value =
|
||||
0.0; // TODO(ianh): This triggers a pointless rebuild.
|
||||
}
|
||||
}
|
||||
@@ -868,26 +904,30 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
|
||||
void didUpdateWidget(_SortArrow oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
bool skipArrow = false;
|
||||
<<<<<<< HEAD
|
||||
final bool newDown = widget.down;
|
||||
=======
|
||||
final bool newDown = widget.down ?? _down!;
|
||||
>>>>>>> upstream/master
|
||||
if (oldWidget.visible != widget.visible) {
|
||||
if (widget.visible &&
|
||||
(_opacityController.status == AnimationStatus.dismissed)) {
|
||||
_orientationController.stop();
|
||||
_orientationController.value = 0.0;
|
||||
if (widget.visible! &&
|
||||
(_opacityController!.status == AnimationStatus.dismissed)) {
|
||||
_orientationController!.stop();
|
||||
_orientationController!.value = 0.0;
|
||||
_orientationOffset = newDown ? 0.0 : math.pi;
|
||||
skipArrow = true;
|
||||
}
|
||||
if (widget.visible) {
|
||||
_opacityController.forward();
|
||||
if ((widget.visible ?? false)) {
|
||||
_opacityController!.forward();
|
||||
} else {
|
||||
_opacityController.reverse();
|
||||
_opacityController!.reverse();
|
||||
}
|
||||
}
|
||||
if ((_down != newDown) && !skipArrow) {
|
||||
if (_orientationController.status == AnimationStatus.dismissed) {
|
||||
_orientationController.forward();
|
||||
if (_orientationController!.status == AnimationStatus.dismissed) {
|
||||
_orientationController?.forward();
|
||||
} else {
|
||||
_orientationController.reverse();
|
||||
_orientationController?.reverse();
|
||||
}
|
||||
}
|
||||
_down = newDown;
|
||||
@@ -895,8 +935,8 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_opacityController.dispose();
|
||||
_orientationController.dispose();
|
||||
_opacityController?.dispose();
|
||||
_orientationController?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -906,10 +946,10 @@ class _SortArrowState extends State<_SortArrow> with TickerProviderStateMixin {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Opacity(
|
||||
opacity: _opacityAnimation.value,
|
||||
opacity: _opacityAnimation!.value,
|
||||
child: Transform(
|
||||
transform:
|
||||
Matrix4.rotationZ(_orientationOffset + _orientationAnimation.value)
|
||||
Matrix4.rotationZ(_orientationOffset + _orientationAnimation!.value)
|
||||
..setTranslationRaw(0.0, _arrowIconBaselineOffset, 0.0),
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
|
||||
Reference in New Issue
Block a user