feat: implement watchPositions() tag position stream
This commit is contained in:
@@ -38,19 +38,42 @@ class PhoenixTagRepository implements TagRepository {
|
||||
Future<void> deleteTag(int id) => tagClient.deleteTag(id);
|
||||
|
||||
@override
|
||||
Stream<List<TagPosition>> watchPositions() =>
|
||||
realtime.channel('tags').map((payload) {
|
||||
final list = payload['positions'] as List<dynamic>? ?? [];
|
||||
return list.map((j) {
|
||||
final m = j as Map<String, dynamic>;
|
||||
return TagPosition(
|
||||
tagId: m['tag_id'] as String,
|
||||
name: m['name'] as String,
|
||||
color: m['color'] as String,
|
||||
roomId: m['room_id'] as int?,
|
||||
);
|
||||
}).toList();
|
||||
});
|
||||
Stream<List<TagPosition>> watchPositions() async* {
|
||||
var tagMap = await _fetchTagMap();
|
||||
|
||||
await for (final occupancy in watchRoomOccupancy()) {
|
||||
// Re-fetch on every occupancy change so name/color edits and new tags
|
||||
// are reflected without restarting the stream.
|
||||
tagMap = await _fetchTagMap();
|
||||
|
||||
final positions = <TagPosition>[];
|
||||
for (final entry in occupancy.entries) {
|
||||
for (final tagId in entry.value) {
|
||||
final tag = tagMap[tagId];
|
||||
positions.add(TagPosition(
|
||||
tagId: tagId,
|
||||
name: tag?.name ?? tagId,
|
||||
color: tag?.color ?? _colorForTagId(tagId),
|
||||
roomId: entry.key,
|
||||
));
|
||||
}
|
||||
}
|
||||
yield positions;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, Tag>> _fetchTagMap() async {
|
||||
final raw = await tagClient.getTags();
|
||||
return {
|
||||
for (final j in raw.cast<Map<String, dynamic>>())
|
||||
j['tag_id'] as String: Tag.fromJson(j),
|
||||
};
|
||||
}
|
||||
|
||||
static String _colorForTagId(String tagId) {
|
||||
final hash = tagId.codeUnits.fold(0, (h, c) => (h * 31 + c) & 0xFFFFFF);
|
||||
return '#${hash.toRadixString(16).padLeft(6, '0')}';
|
||||
}
|
||||
|
||||
@override
|
||||
Stream<ParticleSnapshot> watchParticleCloud(String tagId) =>
|
||||
|
||||
@@ -8,11 +8,13 @@ class Tag {
|
||||
this.currentRoomId,
|
||||
this.lastPosition,
|
||||
this.lastSeen,
|
||||
this.color,
|
||||
});
|
||||
|
||||
final int id;
|
||||
final String tagId; // BLE beacon advertised identifier
|
||||
final String name;
|
||||
final String? color;
|
||||
final String? currentRoomId;
|
||||
final Position? lastPosition;
|
||||
final DateTime? lastSeen;
|
||||
@@ -34,6 +36,7 @@ class Tag {
|
||||
'current_room_id': currentRoomId,
|
||||
'last_position': lastPosition?.toJson(),
|
||||
'last_seen': lastSeen?.toIso8601String(),
|
||||
'color': color,
|
||||
};
|
||||
|
||||
factory Tag.fromJson(Map<String, dynamic> json) => Tag(
|
||||
@@ -41,6 +44,7 @@ class Tag {
|
||||
tagId: json['tag_id'] as String,
|
||||
name: json['name'] as String,
|
||||
currentRoomId: json['current_room_id'] as String?,
|
||||
color: json['color'] as String?,
|
||||
lastPosition: json['last_position'] == null
|
||||
? null
|
||||
: Position.fromJson(json['last_position'] as Map<String, dynamic>),
|
||||
|
||||
Reference in New Issue
Block a user