83 lines
2.5 KiB
Dart
83 lines
2.5 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:webview_flutter/webview_flutter.dart';
|
|
|
|
import '../../../domain/models/floor_plan_mode.dart';
|
|
import '../../../domain/models/tag.dart';
|
|
import '../../../domain/models/particle.dart';
|
|
import '../../../domain/models/position.dart';
|
|
|
|
class KonvaWebView extends StatefulWidget {
|
|
const KonvaWebView({
|
|
super.key,
|
|
required this.mode,
|
|
required this.onSensorTapped,
|
|
required this.onSensorMoved,
|
|
});
|
|
|
|
final FloorPlanMode mode;
|
|
final void Function(String sensorId) onSensorTapped;
|
|
final void Function(String sensorId, Position newPosition) onSensorMoved;
|
|
|
|
@override
|
|
State<KonvaWebView> createState() => KonvaWebViewState();
|
|
}
|
|
|
|
class KonvaWebViewState extends State<KonvaWebView> {
|
|
late final WebViewController _controller;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_controller = WebViewController()
|
|
..setJavaScriptMode(JavaScriptMode.unrestricted)
|
|
..addJavaScriptChannel('FlutterBridge', onMessageReceived: _onMessage)
|
|
..loadFlutterAsset('assets/konva/index.html');
|
|
}
|
|
|
|
void _onMessage(JavaScriptMessage message) {
|
|
final data = jsonDecode(message.message) as Map<String, dynamic>;
|
|
switch (data['type'] as String?) {
|
|
case 'sensorTapped':
|
|
widget.onSensorTapped(data['id'] as String);
|
|
case 'sensorMoved':
|
|
widget.onSensorMoved(
|
|
data['id'] as String,
|
|
Position(
|
|
x: (data['x'] as num).toDouble(),
|
|
y: (data['y'] as num).toDouble(),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> updateTags(List<TagPosition> positions) async {
|
|
final payload = jsonEncode(positions
|
|
.map((p) => {'tagId': p.tagId, 'x': p.position.x, 'y': p.position.y})
|
|
.toList());
|
|
await _controller.runJavaScript('window.companion.updateTags($payload)');
|
|
}
|
|
|
|
Future<void> updateParticleCloud(List<Particle> particles) async {
|
|
final payload = jsonEncode(particles
|
|
.map((p) => {'x': p.x, 'y': p.y, 'weight': p.weight})
|
|
.toList());
|
|
await _controller.runJavaScript('window.companion.updateCloud($payload)');
|
|
}
|
|
|
|
Future<void> highlightSensor(String? sensorId) async {
|
|
final id = sensorId == null ? 'null' : '"$sensorId"';
|
|
await _controller.runJavaScript('window.companion.highlightSensor($id)');
|
|
}
|
|
|
|
Future<void> setMode(FloorPlanMode mode) async {
|
|
await _controller.runJavaScript(
|
|
'window.companion.setMode("${mode.name}")',
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) => WebViewWidget(controller: _controller);
|
|
}
|