added unit test
This commit is contained in:
@@ -328,7 +328,7 @@ class _CustomerWidgetState extends State<CustomerWidget> {
|
||||
}
|
||||
|
||||
Future<void> _actionSelect(BuildContext context, CustomerDto customerDto, PictureDto pictureDto) async {
|
||||
String uri = "${GlobalRouter.pathHome}${GlobalRouter.pathPicture}/${customerDto.id}/${pictureDto.id}";
|
||||
String uri = "${GlobalRouter.pathHome}${GlobalRouter.pathCustomer}/${customerDto.id}${GlobalRouter.pathPicture}/${pictureDto.id}";
|
||||
context.go(uri);
|
||||
setState(() {
|
||||
_dto = _customerController.get(id: widget.customerId);
|
||||
|
||||
@@ -14,41 +14,55 @@ class PictureFullscreenDialog extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final screenSize = MediaQuery.of(context).size;
|
||||
final dialogWidth = screenSize.width * 0.9;
|
||||
final dialogHeight = screenSize.height * 0.9 - 50;
|
||||
|
||||
final imageBytes = base64Decode(dto.image);
|
||||
return Dialog(
|
||||
backgroundColor: _generalStyle.pageBackgroundColor,
|
||||
insetPadding: const EdgeInsets.all(24),
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.9,
|
||||
height: MediaQuery.of(context).size.height * 0.9,
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
InteractiveViewer(
|
||||
panEnabled: true,
|
||||
scaleEnabled: true,
|
||||
minScale: 0.5,
|
||||
maxScale: 5.0,
|
||||
child: Center(
|
||||
child: Image.memory(
|
||||
base64Decode(dto.image),
|
||||
fit: BoxFit.contain,
|
||||
backgroundColor: Colors.black,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8.0, right: 8.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
IconButton(
|
||||
style: IconButton.styleFrom(
|
||||
backgroundColor: _generalStyle.primaryButtonBackgroundColor,
|
||||
shape: const CircleBorder(),
|
||||
minimumSize: const Size(36, 36),
|
||||
padding: const EdgeInsets.all(6),
|
||||
),
|
||||
icon: const Icon(Icons.close, color: Colors.white, size: 20),
|
||||
onPressed: () async => await _actionBack(context),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
top: 16,
|
||||
right: 16,
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.close, color: _generalStyle.primaryButtonBackgroundColor, size: 32),
|
||||
onPressed: () => Navigator.of(context).pop(),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: dialogWidth,
|
||||
height: dialogHeight,
|
||||
child: InteractiveViewer(
|
||||
constrained: true,
|
||||
//boundaryMargin: EdgeInsets.all(20),
|
||||
panEnabled: true,
|
||||
scaleEnabled: true,
|
||||
minScale: 0.5,
|
||||
maxScale: 5.0,
|
||||
child: Image.memory(
|
||||
imageBytes,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _actionBack(BuildContext context) async {
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,13 +113,17 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
return LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
final isNarrow = constraints.maxWidth < 800;
|
||||
final maxImageWidth = constraints.maxWidth * 0.5;
|
||||
return SingleChildScrollView(
|
||||
child: isNarrow
|
||||
? Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_imageWidget(selectedPicture),
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: maxImageWidth),
|
||||
child: _imageWidget(selectedPicture),
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
_contentWidget(selectedPicture),
|
||||
],
|
||||
@@ -128,7 +132,10 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_imageWidget(selectedPicture),
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(maxWidth: maxImageWidth),
|
||||
child: _imageWidget(selectedPicture),
|
||||
),
|
||||
const SizedBox(width: 32),
|
||||
Expanded(child: _contentWidget(selectedPicture)),
|
||||
],
|
||||
@@ -142,7 +149,7 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
return GestureDetector(
|
||||
key: const Key("image"),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () => _showFullscreenImage(dto),
|
||||
onTap: () => _actionShowFullscreenImage(dto),
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: ConstrainedBox(
|
||||
@@ -156,15 +163,6 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
void _showFullscreenImage(PictureDto dto) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return PictureFullscreenDialog(dto: dto);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _contentWidget(PictureDto dto) {
|
||||
final labelStyle = TextStyle(
|
||||
fontWeight: FontWeight.normal,
|
||||
@@ -211,9 +209,12 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
style: contentStyle,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
AppLocalizations.of(context)!.pictureWidgetLabelZip,
|
||||
style: labelStyle,
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 24.0),
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.pictureWidgetLabelZip,
|
||||
style: labelStyle,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
@@ -222,9 +223,12 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
style: contentStyle,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
AppLocalizations.of(context)!.pictureWidgetLabelCity,
|
||||
style: labelStyle,
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 24.0),
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.pictureWidgetLabelCity,
|
||||
style: labelStyle,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
@@ -233,32 +237,6 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
style: contentStyle,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 20.0),
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.pictureWidgetLabelComment,
|
||||
style: labelStyle,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: 150,
|
||||
child: Scrollbar(
|
||||
controller: _commentScrollController,
|
||||
thumbVisibility: true,
|
||||
child: SingleChildScrollView(
|
||||
controller: _commentScrollController,
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
dto.comment ?? "",
|
||||
style: contentStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -266,6 +244,32 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
_evaluationCard(dto),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 24.0),
|
||||
child: Text(
|
||||
AppLocalizations.of(context)!.pictureWidgetLabelComment,
|
||||
style: labelStyle,
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 4.0),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
height: 150,
|
||||
child: Scrollbar(
|
||||
controller: _commentScrollController,
|
||||
thumbVisibility: true,
|
||||
child: SingleChildScrollView(
|
||||
controller: _commentScrollController,
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
dto.comment ?? "",
|
||||
style: contentStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -332,8 +336,8 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
onTap: () async => _actionUpdateEvaluation(value),
|
||||
customBorder: const CircleBorder(),
|
||||
child: Container(
|
||||
width: 32,
|
||||
height: 32,
|
||||
width: 24,
|
||||
height: 24,
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
shape: BoxShape.circle,
|
||||
@@ -345,10 +349,14 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
|
||||
// Bottom navigation buttons
|
||||
Widget _bottomNavigationWidget(List<PictureDto> pictures, PictureDto selectedPicture) {
|
||||
pictures.sort((a, b) => a.pictureDate.compareTo(b.pictureDate));
|
||||
print(pictures);
|
||||
final currentIndex = pictures.indexWhere((p) => p.id == selectedPicture.id);
|
||||
final hasPrevious = currentIndex > 0;
|
||||
final hasNext = currentIndex < pictures.length - 1;
|
||||
|
||||
print("hasnext $hasNext hasPrevious $hasPrevious current $currentIndex");
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.only(bottom: 24.0),
|
||||
child: Row(
|
||||
@@ -405,6 +413,15 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
void _actionShowFullscreenImage(PictureDto dto) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return PictureFullscreenDialog(dto: dto);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _actionUpdateEvaluation(int value) async {
|
||||
_selectedPicture?.evaluation = value;
|
||||
_pictureController.updateEvaluation(_selectedPicture!);
|
||||
@@ -412,11 +429,14 @@ class _PictureWidgetState extends State<PictureWidget> {
|
||||
}
|
||||
|
||||
void _actionNavigateToPicture(int index) {
|
||||
print("navigate. too $index");
|
||||
final pictures = _customerDto.pictures;
|
||||
if (index >= 0 && index < pictures.length) {
|
||||
setState(() {
|
||||
_selectedPicture = pictures[index];
|
||||
});
|
||||
}else {
|
||||
print("empty");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user