Support map on web

This commit is contained in:
Ming Ming 2021-04-20 00:14:32 +08:00
parent 0a0df10972
commit 3a5d6a17a9
7 changed files with 117 additions and 30 deletions

View file

@ -0,0 +1,50 @@
import 'dart:math';
import 'package:flutter/widgets.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:tuple/tuple.dart';
class Map extends StatelessWidget {
const Map({
Key key,
this.center,
this.zoom,
this.onTap,
}) : super(key: key);
@override
build(BuildContext context) {
final centerLl = LatLng(center.item1, center.item2);
return GoogleMap(
compassEnabled: false,
mapToolbarEnabled: false,
rotateGesturesEnabled: false,
scrollGesturesEnabled: false,
zoomControlsEnabled: false,
zoomGesturesEnabled: false,
tiltGesturesEnabled: false,
myLocationButtonEnabled: false,
buildingsEnabled: false,
// liteModeEnabled: true,
initialCameraPosition: CameraPosition(
target: centerLl,
zoom: zoom,
),
markers: {
Marker(
markerId: MarkerId("at"),
position: centerLl,
// for some reason, GoogleMap's onTap is not triggered if
// tapped on top of the marker
onTap: onTap,
),
},
onTap: (_) => onTap?.call(),
);
}
/// A pair of latitude and longitude coordinates, stored as degrees
final Tuple2<double, double> center;
final double zoom;
final void Function() onTap;
}

View file

@ -1,3 +1,4 @@
export 'db_util.dart';
export 'downloader.dart';
export 'map_widget.dart';
export 'metadata_loader.dart';

5
lib/mobile/ui_hack.dart Normal file
View file

@ -0,0 +1,5 @@
// See: https://github.com/flutter/flutter/issues/41563
// ignore: camel_case_types
class platformViewRegistry {
static registerViewFactory(String viewId, dynamic cb) {}
}

View file

@ -2,4 +2,4 @@ import 'dart:io';
import 'package:flutter/foundation.dart';
final isSupportMapView = !kIsWeb && Platform.isAndroid;
final isSupportMapView = kIsWeb || Platform.isAndroid;

49
lib/web/map_widget.dart Normal file
View file

@ -0,0 +1,49 @@
// ignore: avoid_web_libraries_in_flutter
import 'dart:html';
import 'package:/nc_photos/mobile/ui_hack.dart' if (dart.library.html) 'dart:ui'
as ui;
import 'package:flutter/widgets.dart';
import 'package:tuple/tuple.dart';
class Map extends StatefulWidget {
const Map({
Key key,
this.center,
this.zoom,
this.onTap,
}) : super(key: key);
@override
createState() => _MapState();
/// A pair of latitude and longitude coordinates, stored as degrees
final Tuple2<double, double> center;
final double zoom;
final void Function() onTap;
}
class _MapState extends State<Map> {
@override
initState() {
super.initState();
final iframe = IFrameElement()
..src = "https://www.google.com/maps/embed/v1/place?key=$_apiKey"
"&q=${widget.center.item1},${widget.center.item2}"
"&zoom=${widget.zoom}"
..style.border = "none";
ui.platformViewRegistry.registerViewFactory(viewType, (viewId) => iframe);
}
@override
build(BuildContext context) {
return HtmlElementView(
viewType: viewType,
);
}
static const _apiKey = "";
String get viewType =>
"mapIframe(${widget.center.item1},${widget.center.item2})";
}

View file

@ -1,3 +1,4 @@
export 'db_util.dart';
export 'downloader.dart';
export 'map_widget.dart';
export 'metadata_loader.dart';

View file

@ -6,7 +6,6 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:intl/intl.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
@ -17,6 +16,8 @@ import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/exception_util.dart' as exception_util;
import 'package:nc_photos/iterable_extension.dart';
import 'package:nc_photos/k.dart' as k;
import 'package:nc_photos/mobile/platform.dart'
if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform;
import 'package:nc_photos/platform/features.dart' as features;
import 'package:nc_photos/snack_bar_manager.dart';
import 'package:nc_photos/theme.dart';
@ -24,6 +25,7 @@ import 'package:nc_photos/use_case/remove.dart';
import 'package:nc_photos/use_case/update_album.dart';
import 'package:nc_photos/widget/album_picker_dialog.dart';
import 'package:path/path.dart';
import 'package:tuple/tuple.dart';
class ViewerDetailPane extends StatefulWidget {
const ViewerDetailPane({
@ -158,32 +160,11 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
if (features.isSupportMapView && _gps != null)
SizedBox(
height: 256,
child: GoogleMap(
compassEnabled: false,
mapToolbarEnabled: false,
rotateGesturesEnabled: false,
scrollGesturesEnabled: false,
zoomControlsEnabled: false,
zoomGesturesEnabled: false,
tiltGesturesEnabled: false,
myLocationButtonEnabled: false,
buildingsEnabled: false,
// liteModeEnabled: true,
initialCameraPosition: CameraPosition(
target: _gps,
child: platform.Map(
center: _gps,
zoom: 16,
),
markers: {
Marker(
markerId: MarkerId("at"),
position: _gps,
// for some reason, GoogleMap's onTap is not triggered if
// tapped on top of the marker
onTap: _onMapTap,
),
},
onTap: (_) => _onMapTap(),
),
),
],
);
@ -261,7 +242,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
if (Platform.isAndroid) {
final intent = AndroidIntent(
action: "action_view",
data: Uri.encodeFull("geo:${_gps.latitude},${_gps.longitude}?z=16"),
data: Uri.encodeFull("geo:${_gps.item1},${_gps.item2}?z=16"),
);
intent.launch();
}
@ -325,7 +306,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
(exif.gpsLongitudeRef == "W" ? -1 : 1);
_log.fine("GPS: ($lat, $lng)");
setState(() {
_gps = LatLng(lat, lng);
_gps = Tuple2(lat, lng);
});
}
}
@ -384,7 +365,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
String _exposureTime;
double _focalLength;
int _isoSpeedRatings;
LatLng _gps;
Tuple2<double, double> _gps;
static final _log =
Logger("widget.viewer_detail_pane._ViewerDetailPaneState");