diff --git a/assets/mapbox_map.html b/assets/mapbox_map.html index eb47f2e..4ed79fe 100644 --- a/assets/mapbox_map.html +++ b/assets/mapbox_map.html @@ -14848,8 +14848,8 @@ el.addEventListener("click", function (e) { e.stopPropagation(); showTrainDetails(lat, lng, recordData); - if (window.flutter_inappwebview) { - window.flutter_inappwebview.callHandler("showTrainDetails", { + if (window.showTrainDetails) { + window.showTrainDetails.postMessage(JSON.stringify({ id: recordData.id || Date.now(), trainNumber: trainNumber || "未知车次", trainType: recordData.trainType || "未知类型", @@ -14858,7 +14858,7 @@ latitude: lat, longitude: lng, timestamp: Date.now(), - }); + })); } }); const marker = new maplibregl.Marker({ @@ -14931,11 +14931,21 @@ .addTo(map); } function setCenter(lat, lng, zoom, bearing) { - map.jumpTo({ + if (!window.map) { + console.error("[JS] Map object not ready in setCenter"); + return; + } + + window.map.jumpTo({ center: [lng, lat], - zoom: zoom !== undefined ? zoom : map.getZoom(), - bearing: bearing !== undefined ? bearing : map.getBearing(), + zoom: zoom !== undefined ? zoom : window.map.getZoom(), + bearing: bearing !== undefined ? bearing : window.map.getBearing(), }); + + const mapContainer = window.map.getContainer(); + if (mapContainer.style.opacity === "0") { + mapContainer.style.opacity = "1"; + } } function getMapState() { const center = map.getCenter(); @@ -14948,17 +14958,19 @@ } function setupMapEventListeners() { if (!map) return; - map.on("moveend", function () { + map.on("move", function () { const center = map.getCenter(); const zoom = map.getZoom(); const bearing = map.getBearing(); - if (window.flutter_inappwebview) { - window.flutter_inappwebview.callHandler("onMapStateChanged", { + + if (window.onMapStateChanged) { + const mapState = JSON.stringify({ lat: center.lat, lng: center.lng, zoom: zoom, bearing: bearing, }); + window.onMapStateChanged.postMessage(mapState); } }); } diff --git a/lib/screens/map_webview_screen.dart b/lib/screens/map_webview_screen.dart index 45c6778..d86967b 100644 --- a/lib/screens/map_webview_screen.dart +++ b/lib/screens/map_webview_screen.dart @@ -32,13 +32,41 @@ class MapWebViewScreenState extends State double _currentRotation = 0.0; LatLng? _currentLocation; LatLng? _lastTrainLocation; + bool _isDataLoaded = false; + final Completer _webViewReadyCompleter = Completer(); @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); _initializeWebView(); - _initializeServices(); + _startInitialization(); + } + + Future _startInitialization() async { + setState(() { + _isLoading = true; + }); + + try { + await _loadSettings(); + await _loadTrainRecordsFromDatabase(); + + await _webViewReadyCompleter.future; + + _initializeMapCamera(); + + _initializeLocation(); + _startAutoRefresh(); + } catch (e, s) { + print('[Flutter] Init Map WebView Screen Failed: $e\n$s'); + } finally { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + } } @override @@ -48,16 +76,7 @@ class MapWebViewScreenState extends State } } - Future _initializeServices() async { - try { - await _loadSettings(); - await _loadTrainRecordsFromDatabase(); - _initializeLocation(); - _startAutoRefresh(); - } catch (e) {} - } - - void _initializeWebView() { + Future _initializeWebView() async { _controller = WebViewController() ..setJavaScriptMode(JavaScriptMode.unrestricted) ..setBackgroundColor(const Color(0xFF121212)) @@ -92,9 +111,8 @@ class MapWebViewScreenState extends State _isLoading = false; }); - if (mounted) { - _initializeMap(); - _initializeLocation(); + if (!_webViewReadyCompleter.isCompleted) { + _webViewReadyCompleter.complete(); } }, onWebResourceError: (WebResourceError error) { @@ -107,6 +125,8 @@ class MapWebViewScreenState extends State ..loadFlutterAsset('assets/mapbox_map.html') .then((_) {}) .catchError((error) {}); + + await Future.delayed(const Duration(milliseconds: 500)); } Future _initializeLocation() async { @@ -266,10 +286,6 @@ class MapWebViewScreenState extends State } else {} } else {} } else {} - - if (mounted) { - _initializeMapPosition(); - } }); Future.delayed(const Duration(milliseconds: 3000), () { @@ -351,25 +367,38 @@ class MapWebViewScreenState extends State } } - void _initializeMapPosition() { + void _initializeMapCamera() { if (_isMapInitialized) return; - LatLng? targetLocation; + LatLng targetLocation; + double targetZoom = _currentZoom; + double targetRotation = _currentRotation; - if (_lastTrainLocation != null) { - targetLocation = _lastTrainLocation; - } else if (_currentPosition != null) { - targetLocation = - LatLng(_currentPosition!.latitude, _currentPosition!.longitude); - } - - if (targetLocation != null) { - _centerMap(targetLocation, - zoom: _currentZoom, rotation: _currentRotation); - _isMapInitialized = true; + if (_currentLocation != null) { + targetLocation = _currentLocation!; + } else if (_lastTrainLocation != null) { + targetLocation = _lastTrainLocation!; + targetZoom = 14.0; + targetRotation = 0.0; } else { - _isMapInitialized = true; + targetLocation = const LatLng(39.9042, 116.4074); + targetZoom = 10.0; } + + _centerMap(targetLocation, zoom: targetZoom, rotation: targetRotation); + _isMapInitialized = true; + + Future.delayed(const Duration(milliseconds: 500), () { + if (mounted) { + _updateUserLocation(); + _updateTrainMarkers(); + _controller.runJavaScript(''' + if (window.MapInterface) { + window.MapInterface.setRailwayVisible($_isRailwayLayerVisible); + } + '''); + } + }); } void _centerMap(LatLng location, {double? zoom, double? rotation}) { @@ -430,91 +459,6 @@ class MapWebViewScreenState extends State } catch (e) {} } - Future _initializeMap() async { - try { - LatLng? targetLocation; - double targetZoom = 14.0; - double targetRotation = _currentRotation; - - if (_lastTrainLocation != null) { - targetLocation = _lastTrainLocation; - targetZoom = 14.0; - targetRotation = 0.0; - } else if (_currentPosition != null) { - targetLocation = - LatLng(_currentPosition!.latitude, _currentPosition!.longitude); - targetZoom = 16.0; - targetRotation = 0.0; - } - - if (targetLocation != null) { - _centerMap(targetLocation, zoom: targetZoom, rotation: targetRotation); - - try { - await _controller.runJavaScript(''' - (function() { - if (window.map && window.map.getContainer) { - window.map.getContainer().style.opacity = '1'; - return true; - } else { - return false; - } - })(); - '''); - } catch (e) { - print('显示地图失败: $e'); - Future.delayed(const Duration(milliseconds: 500), () { - _controller.runJavaScript(''' - (function() { - if (window.map && window.map.getContainer) { - window.map.getContainer().style.opacity = '1'; - console.log('延迟显示地图成功'); - } - })(); - '''); - }); - } - } - - setState(() { - _isMapInitialized = true; - }); - } catch (e, stackTrace) {} - - Future.delayed(const Duration(milliseconds: 1000), () { - if (mounted && _isMapInitialized) { - _updateTrainMarkers(); - - _controller.runJavaScript(''' - (function() { - if (window.MapInterface) { - try { - window.MapInterface.setRailwayVisible($_isRailwayLayerVisible); - console.log('初始化铁路图层状态: $_isRailwayLayerVisible'); - } catch (error) { - console.error('初始化铁路图层失败:', error); - } - } - })(); - '''); - } - }); - - Future.delayed(const Duration(milliseconds: 3000), () { - if (mounted && _isMapInitialized) { - _updateTrainMarkers(); - } - }); - - Future.delayed(const Duration(seconds: 5), () { - if (mounted && _isLoading) { - setState(() { - _isLoading = false; - }); - } - }); - } - LatLng? _parseDmsCoordinate(String? positionInfo) { if (positionInfo == null || positionInfo.isEmpty || @@ -943,10 +887,10 @@ class MapWebViewScreenState extends State void _onMapStateChanged(Map mapState) { try { - final lat = mapState['lat'] as double; - final lng = mapState['lng'] as double; - final zoom = mapState['zoom'] as double; - final bearing = mapState['bearing'] as double; + final lat = (mapState['lat'] as num).toDouble(); + final lng = (mapState['lng'] as num).toDouble(); + final zoom = (mapState['zoom'] as num).toDouble(); + final bearing = (mapState['bearing'] as num).toDouble(); setState(() { _currentLocation = LatLng(lat, lng); diff --git a/lib/services/database_service.dart b/lib/services/database_service.dart index 482212e..3d0dd92 100644 --- a/lib/services/database_service.dart +++ b/lib/services/database_service.dart @@ -13,7 +13,7 @@ class DatabaseService { DatabaseService._internal(); static const String _databaseName = 'train_database'; - static const _databaseVersion = 6; + static const _databaseVersion = 7; static const String trainRecordsTable = 'train_records'; static const String appSettingsTable = 'app_settings'; @@ -87,6 +87,10 @@ class DatabaseService { await db.execute( 'ALTER TABLE $appSettingsTable ADD COLUMN hideUngroupableRecords INTEGER NOT NULL DEFAULT 0'); } + if (oldVersion < 7) { + await db.execute( + 'ALTER TABLE $appSettingsTable ADD COLUMN mapSettingsTimestamp INTEGER'); + } } Future _onCreate(Database db, int version) async { @@ -136,7 +140,8 @@ class DatabaseService { groupBy TEXT NOT NULL DEFAULT 'trainAndLoco', timeWindow TEXT NOT NULL DEFAULT 'unlimited', mapTimeFilter TEXT NOT NULL DEFAULT 'unlimited', - hideUngroupableRecords INTEGER NOT NULL DEFAULT 0 + hideUngroupableRecords INTEGER NOT NULL DEFAULT 0, + mapSettingsTimestamp INTEGER ) '''); @@ -164,6 +169,7 @@ class DatabaseService { 'timeWindow': 'unlimited', 'mapTimeFilter': 'unlimited', 'hideUngroupableRecords': 0, + 'mapSettingsTimestamp': null, }); } diff --git a/pubspec.yaml b/pubspec.yaml index 3134fd5..e591ac7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 0.5.0-flutter+50 +version: 0.5.1-flutter+51 environment: sdk: ^3.5.4