Skip to content

Commit d7be623

Browse files
committed
feat: VideoOverlay serialization
1 parent 41dfcdd commit d7be623

File tree

4 files changed

+107
-2
lines changed

4 files changed

+107
-2
lines changed

lib/models/device.dart

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import 'dart:convert';
2121

2222
import 'package:bluecherry_client/models/server.dart';
2323
import 'package:bluecherry_client/providers/server_provider.dart';
24+
import 'package:bluecherry_client/utils/config.dart';
2425
import 'package:bluecherry_client/utils/extensions.dart';
2526
import 'package:bluecherry_client/widgets/device_grid/desktop/external_stream.dart';
2627
import 'package:flutter/foundation.dart';
@@ -53,6 +54,8 @@ class Device {
5354

5455
final MatrixType matrixType;
5556

57+
final List<VideoOverlay> overlays;
58+
5659
/// Creates a device.
5760
Device(
5861
this.name,
@@ -64,6 +67,7 @@ class Device {
6467
this.hasPTZ = false,
6568
this.url,
6669
this.matrixType = MatrixType.t16,
70+
this.overlays = const [],
6771
});
6872

6973
Device.dump({
@@ -75,6 +79,7 @@ class Device {
7579
this.hasPTZ = false,
7680
this.url,
7781
this.matrixType = MatrixType.t16,
82+
this.overlays = const [],
7883
}) : server = Server.dump();
7984

8085
String get uri => 'live/$id';
@@ -226,7 +231,8 @@ class Device {
226231
resolutionY == other.resolutionY &&
227232
hasPTZ == other.hasPTZ &&
228233
url == other.url &&
229-
matrixType == other.matrixType;
234+
matrixType == other.matrixType &&
235+
overlays == other.overlays;
230236
}
231237

232238
@override
@@ -238,7 +244,8 @@ class Device {
238244
resolutionY.hashCode ^
239245
hasPTZ.hashCode ^
240246
url.hashCode ^
241-
matrixType.hashCode;
247+
matrixType.hashCode ^
248+
overlays.hashCode;
242249

243250
Device copyWith({
244251
String? name,
@@ -250,6 +257,7 @@ class Device {
250257
bool? hasPTZ,
251258
String? url,
252259
MatrixType? matrixType,
260+
List<VideoOverlay>? overlays,
253261
}) =>
254262
Device(
255263
name ?? this.name,
@@ -261,6 +269,7 @@ class Device {
261269
hasPTZ: hasPTZ ?? this.hasPTZ,
262270
url: url ?? this.url,
263271
matrixType: matrixType ?? this.matrixType,
272+
overlays: overlays ?? this.overlays,
264273
);
265274

266275
Map<String, dynamic> toJson() {
@@ -274,6 +283,7 @@ class Device {
274283
'hasPTZ': hasPTZ,
275284
'url': url,
276285
'matrixType': matrixType.index,
286+
'overlays': overlays.map((e) => e.toMap()).toList(),
277287
};
278288
}
279289

@@ -291,6 +301,10 @@ class Device {
291301
hasPTZ: json['hasPTZ'] ?? false,
292302
url: json['url'],
293303
matrixType: MatrixType.values[json['matrixType'] ?? 0],
304+
overlays: json['overlays'] != null
305+
? List<VideoOverlay>.from(
306+
(json['overlays'] as List).cast<Map>().map(VideoOverlay.fromMap))
307+
: [],
294308
);
295309
}
296310
}

lib/utils/config.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,35 @@ class VideoOverlay {
4444
this.position = Offset.zero,
4545
this.visible = true,
4646
});
47+
48+
Map<String, dynamic> toMap() {
49+
return {
50+
'text': text,
51+
'textStyle': {
52+
'color': textStyle?.color?.value.toRadixString(16),
53+
'fontSize': textStyle?.fontSize,
54+
},
55+
'position_x': position.dx,
56+
'position_y': position.dy,
57+
'visible': visible,
58+
};
59+
}
60+
61+
factory VideoOverlay.fromMap(Map map) {
62+
return VideoOverlay(
63+
text: map['text'] ?? '',
64+
textStyle: TextStyle(
65+
color: map['textStyle']['color'] == null
66+
? null
67+
: Color(int.parse(
68+
'0xFF${(map['textStyle']['color'] as String).replaceAll('#', '')}',
69+
)),
70+
fontSize: (map['textStyle']['fontSize'] as num?)?.toDouble(),
71+
),
72+
position: Offset(map['position_x'] ?? 0.0, map['position_y'] ?? 0.0),
73+
visible: map['visible'] ?? false,
74+
);
75+
}
4776
}
4877

4978
/// Parses the config file content and returns a map with the config values.

pubspec.lock

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,22 @@ packages:
405405
url: "https://pub.dev"
406406
source: hosted
407407
version: "4.8.1"
408+
leak_tracker:
409+
dependency: transitive
410+
description:
411+
name: leak_tracker
412+
sha256: "2c30f27ada446b4d36307aade893faaaeb6d8f55b2362b7f424a9668fcc43f4d"
413+
url: "https://pub.dev"
414+
source: hosted
415+
version: "9.0.14"
416+
leak_tracker_testing:
417+
dependency: transitive
418+
description:
419+
name: leak_tracker_testing
420+
sha256: b06739349ec2477e943055aea30172c5c7000225f79dad4702e2ec0eda79a6ff
421+
url: "https://pub.dev"
422+
source: hosted
423+
version: "1.0.5"
408424
lints:
409425
dependency: transitive
410426
description:
@@ -998,6 +1014,14 @@ packages:
9981014
url: "https://pub.dev"
9991015
source: hosted
10001016
version: "3.0.2"
1017+
vm_service:
1018+
dependency: transitive
1019+
description:
1020+
name: vm_service
1021+
sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
1022+
url: "https://pub.dev"
1023+
source: hosted
1024+
version: "13.0.0"
10011025
volume_controller:
10021026
dependency: transitive
10031027
description:

test/configuration_file.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import 'package:bluecherry_client/utils/config.dart';
2+
import 'package:flutter/widgets.dart';
3+
import 'package:flutter_test/flutter_test.dart';
4+
5+
void main() {
6+
test('VideoOverlay serialization', () {
7+
const overlay = VideoOverlay(
8+
text: 'My overlay',
9+
textStyle: TextStyle(
10+
color: Color(0xFF000000),
11+
fontSize: 12.0,
12+
),
13+
position: Offset(10.0, 10.0),
14+
);
15+
16+
final map = overlay.toMap();
17+
expect(
18+
map,
19+
{
20+
'text': 'My overlay',
21+
'textStyle': {
22+
'color': 'ff000000',
23+
'fontSize': 12.0,
24+
},
25+
'position_x': 10.0,
26+
'position_y': 10.0,
27+
'visible': true,
28+
},
29+
);
30+
31+
final overlay2 = VideoOverlay.fromMap(map);
32+
expect(overlay2.text, 'My overlay');
33+
expect(overlay2.textStyle?.color, const Color(0xFF000000));
34+
expect(overlay2.textStyle?.fontSize, 12.0);
35+
expect(overlay2.position, const Offset(10.0, 10.0));
36+
expect(overlay2.visible, true);
37+
});
38+
}

0 commit comments

Comments
 (0)