Skip to content

Commit 7085fd4

Browse files
authored
UI zones (#36)
* Adjust widgets so it doesn't overflow * Adjust size of views * Add zone create button * Fix image not retrieved * Fix saving snapshots error * Formatting * Added schema endpoint for config * Use auto sizing gridview * Start adjusting size * Have more adjustments for number of columns * Add progress indicator when loading the detections
1 parent adf3af8 commit 7085fd4

12 files changed

+130
-26
lines changed

swatch/http.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ def get_config() -> Any:
5757
return make_response(jsonify(current_app.swatch_config.dict()), 200)
5858

5959

60+
@bp.route("/config/schema", methods=["GET"])
61+
def get_config_schema() -> Any:
62+
"""Get schema for the swatch config.
63+
Which is useful for vscode or other code completion."""
64+
return current_app.response_class(
65+
current_app.swatch_config.schema_json(), mimetype="application/json"
66+
)
67+
68+
69+
### Color Testing Routes
70+
71+
6072
@bp.route("/colortest/values", methods=["POST"])
6173
def test_colors() -> Any:
6274
"""Test and get color values inside of test image."""
@@ -390,7 +402,7 @@ def get_detection_snapshot(detection_id: str):
390402
"success": False,
391403
"message": f"Error loading snapshot for {detection_id}.",
392404
},
393-
404,
405+
500,
394406
)
395407

396408
except DoesNotExist:

swatch/snapshot.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,13 @@ def get_detection_snapshot(self, detection: Detection) -> Any:
9898

9999
file = f"{file_dir}/{detection.id}.jpg"
100100

101-
with open(file, "rb") as image_file:
102-
jpg_bytes = image_file.read()
101+
try:
102+
with open(file, "rb") as image_file:
103+
jpg_bytes = image_file.read()
103104

104-
return jpg_bytes
105+
return jpg_bytes
106+
except:
107+
return None
105108

106109
def get_latest_camera_snapshot(
107110
self,

web/lib/components/component_camera.dart

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import 'package:flutter/material.dart';
22
import 'package:swatch/api/api.dart';
3+
import 'package:swatch/components/component_new_zone.dart';
34
import 'package:swatch/components/component_zone.dart';
45
import 'package:swatch/ext/extension_string.dart';
56
import 'package:swatch/models/camera.dart';
67

78
class CameraComponent extends StatelessWidget {
8-
99
final SwatchApi _api = SwatchApi();
1010
final Camera camera;
1111

@@ -48,9 +48,9 @@ class CameraComponent extends StatelessWidget {
4848
),
4949
),
5050
Padding(
51-
padding: const EdgeInsets.fromLTRB(8.0, 24.0, 8.0, 8.0),
51+
padding: const EdgeInsets.fromLTRB(8.0, 4.0, 8.0, 4.0),
5252
child: Column(
53-
mainAxisAlignment: MainAxisAlignment.end,
53+
mainAxisAlignment: MainAxisAlignment.start,
5454
crossAxisAlignment: CrossAxisAlignment.start,
5555
children: [
5656
const Text(
@@ -71,7 +71,16 @@ class CameraComponent extends StatelessWidget {
7171

7272
List<Widget> _getZones(Camera config) {
7373
final keys = config.zones.keys.toList();
74-
return List.generate(config.zones.length,
75-
(index) => ZoneComponent(config, config.zones[keys[index]]!));
74+
return List.generate(
75+
config.zones.length + 1,
76+
(index) {
77+
if (index < config.zones.length) {
78+
return ZoneComponent(config, config.zones[keys[index]]!);
79+
} else {
80+
return const SizedBox();
81+
//return const CreateZoneComponent();
82+
}
83+
},
84+
);
7685
}
7786
}

web/lib/components/component_detection.dart

+9-4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ class DetectionComponent extends StatelessWidget {
2626
"${_api.getHost()}/api/detections/${event.id}/snapshot.jpg",
2727
height: 100.0,
2828
fit: BoxFit.fill,
29+
errorBuilder: (context, obj, str) {
30+
return Container(
31+
width: 120.0,
32+
height: 100.0,
33+
color: Colors.black,
34+
);
35+
},
2936
),
3037
),
3138
Padding(
@@ -63,8 +70,7 @@ class DetectionComponent extends StatelessWidget {
6370
size: 18.0,
6471
),
6572
Padding(
66-
padding:
67-
const EdgeInsets.symmetric(horizontal: 4.0),
73+
padding: const EdgeInsets.symmetric(horizontal: 4.0),
6874
child: Text(
6975
event.getCamera(),
7076
textAlign: TextAlign.center,
@@ -96,8 +102,7 @@ class DetectionComponent extends StatelessWidget {
96102
size: 18.0,
97103
),
98104
Padding(
99-
padding:
100-
const EdgeInsets.symmetric(horizontal: 4.0),
105+
padding: const EdgeInsets.symmetric(horizontal: 4.0),
101106
child: Text(
102107
event.getColorVariant(),
103108
textAlign: TextAlign.center,
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:swatch/theme/theme_helper.dart';
3+
4+
class CreateZoneComponent extends StatelessWidget {
5+
const CreateZoneComponent({Key? key}) : super(key: key);
6+
7+
@override
8+
Widget build(BuildContext context) {
9+
return Card(
10+
color: Colors.grey[700],
11+
shape: const RoundedRectangleBorder(
12+
borderRadius: BorderRadius.all(
13+
Radius.circular(8.0),
14+
),
15+
),
16+
child: SizedBox(
17+
width: 98.0,
18+
height: 104.0,
19+
child: IconButton(
20+
icon: Icon(
21+
Icons.add_location_alt_outlined,
22+
color: SwatchColors.getPrimaryColor(),
23+
),
24+
onPressed: () {},
25+
),
26+
),
27+
);
28+
}
29+
}

web/lib/components/component_zone.dart

+3-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import 'package:swatch/models/camera.dart';
55
import 'package:swatch/models/zone.dart';
66

77
class ZoneComponent extends StatelessWidget {
8-
98
final SwatchApi _api = SwatchApi();
109
final Camera camera;
1110
final Zone zone;
@@ -26,20 +25,19 @@ class ZoneComponent extends StatelessWidget {
2625
),
2726
),
2827
child: Column(
29-
mainAxisSize: MainAxisSize.min,
30-
mainAxisAlignment: MainAxisAlignment.start,
28+
mainAxisSize: MainAxisSize.max,
29+
mainAxisAlignment: MainAxisAlignment.end,
3130
crossAxisAlignment: CrossAxisAlignment.start,
3231
children: [
3332
ClipRRect(
3433
borderRadius: const BorderRadius.all(Radius.circular(8.0)),
3534
child: Image.network(
3635
"${_api.getHost()}/api/${camera.name}/${zone.name}/snapshot.jpg",
37-
height: 100,
3836
fit: BoxFit.fill,
3937
),
4038
),
4139
Padding(
42-
padding: const EdgeInsets.all(8.0),
40+
padding: const EdgeInsets.fromLTRB(8.0, 4.0, 8.0, 4.0),
4341
child: Text(
4442
zone.name.replaceAll('_', ' ').title(),
4543
style: const TextStyle(

web/lib/ext/extension_double.dart

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
extension IntExtension on double {
2+
3+
int getColumnsForWidth() {
4+
if (this < 600) {
5+
return 1;
6+
} else if (this < 1200) {
7+
return 2;
8+
} else if (this < 1800) {
9+
return 3;
10+
} else {
11+
return 4;
12+
}
13+
}
14+
}

web/lib/routes/route_adjust_zone.dart

Whitespace-only changes.

web/lib/routes/route_dashboard.dart

+13-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
21
import 'package:flutter/material.dart';
2+
import 'package:flutter_layout_grid/flutter_layout_grid.dart';
33
import 'package:swatch/api/api.dart';
44
import 'package:swatch/components/component_camera.dart';
55
import 'package:swatch/const.dart';
6+
import 'package:swatch/ext/extension_double.dart';
67
import 'package:swatch/models/config.dart';
78

89
import 'package:collapsible_sidebar/collapsible_sidebar.dart';
@@ -18,7 +19,6 @@ class DashboardRoute extends StatefulWidget {
1819
}
1920

2021
class DashboardRouteState extends State<DashboardRoute> {
21-
2222
@override
2323
Widget build(BuildContext context) {
2424
return Scaffold(
@@ -57,18 +57,26 @@ class DashboardRouteState extends State<DashboardRoute> {
5757
}
5858
}
5959

60-
class _DashboardView extends StatelessWidget {
60+
class _DashboardView extends StatefulWidget {
61+
@override
62+
State<_DashboardView> createState() => _DashboardViewState();
63+
}
64+
65+
class _DashboardViewState extends State<_DashboardView> {
6166
final SwatchApi _api = SwatchApi();
6267

6368
@override
6469
Widget build(BuildContext context) {
70+
final columnCount = MediaQuery.of(context).size.width.getColumnsForWidth();
71+
6572
return Scaffold(
6673
body: FutureBuilder(
6774
future: _api.getConfig(),
6875
builder: (context, AsyncSnapshot<Config> config) {
6976
if (config.hasData) {
70-
return GridView.extent(
71-
maxCrossAxisExtent: 500,
77+
return LayoutGrid(
78+
columnSizes: List.generate(columnCount, (index) => 1.fr),
79+
rowSizes: List.generate(columnCount, (index) => auto),
7280
children: _getCameras(config.data!),
7381
);
7482
} else {

web/lib/routes/route_detections.dart

+13-2
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,28 @@ class _DetectionsViewState extends State<_DetectionsView> {
8181
return ListView(
8282
children: _getDetections(detections.data!),
8383
);
84-
} else {
84+
} else if (detections.hasData && detections.data!.isEmpty) {
8585
return Container(
8686
alignment: Alignment.center,
87-
child: const SizedBox(width: 400.0,
87+
child: const SizedBox(
88+
width: 400.0,
8889
child: Text(
8990
"No detections found. Once an object is detected it will appear here.",
9091
textAlign: TextAlign.center,
9192
style: TextStyle(fontSize: 24.0),
9293
),
9394
),
9495
);
96+
} else {
97+
return Container(
98+
alignment: Alignment.center,
99+
child: SizedBox(
100+
width: 400.0,
101+
child: RefreshProgressIndicator(
102+
color: SwatchColors.getPrimaryColor(),
103+
),
104+
),
105+
);
95106
}
96107
},
97108
),

web/pubspec.lock

+15-1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,13 @@ packages:
6969
description: flutter
7070
source: sdk
7171
version: "0.0.0"
72+
flutter_layout_grid:
73+
dependency: "direct main"
74+
description:
75+
name: flutter_layout_grid
76+
url: "https://pub.dartlang.org"
77+
source: hosted
78+
version: "1.0.6"
7279
flutter_lints:
7380
dependency: "direct dev"
7481
description:
@@ -149,6 +156,13 @@ packages:
149156
url: "https://pub.dartlang.org"
150157
source: hosted
151158
version: "1.8.1"
159+
quiver:
160+
dependency: transitive
161+
description:
162+
name: quiver
163+
url: "https://pub.dartlang.org"
164+
source: hosted
165+
version: "3.1.0"
152166
sky_engine:
153167
dependency: transitive
154168
description: flutter
@@ -219,4 +233,4 @@ packages:
219233
version: "1.0.0"
220234
sdks:
221235
dart: ">=2.17.0 <3.0.0"
222-
flutter: ">=1.17.0"
236+
flutter: ">=1.25.0"

web/pubspec.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dependencies:
1818
# UI
1919
cupertino_icons: ^1.0.2
2020
collapsible_sidebar: ^2.0.1+2
21+
flutter_layout_grid: ^1.0.3
2122

2223
# IO
2324
http: ^0.13.4

0 commit comments

Comments
 (0)