mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-03-25 08:24:43 +01:00
Support map on web
This commit is contained in:
parent
0a0df10972
commit
3a5d6a17a9
7 changed files with 117 additions and 30 deletions
50
lib/mobile/map_widget.dart
Normal file
50
lib/mobile/map_widget.dart
Normal 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;
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
export 'db_util.dart';
|
export 'db_util.dart';
|
||||||
export 'downloader.dart';
|
export 'downloader.dart';
|
||||||
|
export 'map_widget.dart';
|
||||||
export 'metadata_loader.dart';
|
export 'metadata_loader.dart';
|
||||||
|
|
5
lib/mobile/ui_hack.dart
Normal file
5
lib/mobile/ui_hack.dart
Normal 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) {}
|
||||||
|
}
|
|
@ -2,4 +2,4 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
final isSupportMapView = !kIsWeb && Platform.isAndroid;
|
final isSupportMapView = kIsWeb || Platform.isAndroid;
|
||||||
|
|
49
lib/web/map_widget.dart
Normal file
49
lib/web/map_widget.dart
Normal 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})";
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
export 'db_util.dart';
|
export 'db_util.dart';
|
||||||
export 'downloader.dart';
|
export 'downloader.dart';
|
||||||
|
export 'map_widget.dart';
|
||||||
export 'metadata_loader.dart';
|
export 'metadata_loader.dart';
|
||||||
|
|
|
@ -6,7 +6,6 @@ import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.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:intl/intl.dart';
|
||||||
import 'package:logging/logging.dart';
|
import 'package:logging/logging.dart';
|
||||||
import 'package:nc_photos/account.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/exception_util.dart' as exception_util;
|
||||||
import 'package:nc_photos/iterable_extension.dart';
|
import 'package:nc_photos/iterable_extension.dart';
|
||||||
import 'package:nc_photos/k.dart' as k;
|
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/platform/features.dart' as features;
|
||||||
import 'package:nc_photos/snack_bar_manager.dart';
|
import 'package:nc_photos/snack_bar_manager.dart';
|
||||||
import 'package:nc_photos/theme.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/use_case/update_album.dart';
|
||||||
import 'package:nc_photos/widget/album_picker_dialog.dart';
|
import 'package:nc_photos/widget/album_picker_dialog.dart';
|
||||||
import 'package:path/path.dart';
|
import 'package:path/path.dart';
|
||||||
|
import 'package:tuple/tuple.dart';
|
||||||
|
|
||||||
class ViewerDetailPane extends StatefulWidget {
|
class ViewerDetailPane extends StatefulWidget {
|
||||||
const ViewerDetailPane({
|
const ViewerDetailPane({
|
||||||
|
@ -158,32 +160,11 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
|
||||||
if (features.isSupportMapView && _gps != null)
|
if (features.isSupportMapView && _gps != null)
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 256,
|
height: 256,
|
||||||
child: GoogleMap(
|
child: platform.Map(
|
||||||
compassEnabled: false,
|
center: _gps,
|
||||||
mapToolbarEnabled: false,
|
|
||||||
rotateGesturesEnabled: false,
|
|
||||||
scrollGesturesEnabled: false,
|
|
||||||
zoomControlsEnabled: false,
|
|
||||||
zoomGesturesEnabled: false,
|
|
||||||
tiltGesturesEnabled: false,
|
|
||||||
myLocationButtonEnabled: false,
|
|
||||||
buildingsEnabled: false,
|
|
||||||
// liteModeEnabled: true,
|
|
||||||
initialCameraPosition: CameraPosition(
|
|
||||||
target: _gps,
|
|
||||||
zoom: 16,
|
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,
|
||||||
),
|
),
|
||||||
},
|
|
||||||
onTap: (_) => _onMapTap(),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -261,7 +242,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
|
||||||
if (Platform.isAndroid) {
|
if (Platform.isAndroid) {
|
||||||
final intent = AndroidIntent(
|
final intent = AndroidIntent(
|
||||||
action: "action_view",
|
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();
|
intent.launch();
|
||||||
}
|
}
|
||||||
|
@ -325,7 +306,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
|
||||||
(exif.gpsLongitudeRef == "W" ? -1 : 1);
|
(exif.gpsLongitudeRef == "W" ? -1 : 1);
|
||||||
_log.fine("GPS: ($lat, $lng)");
|
_log.fine("GPS: ($lat, $lng)");
|
||||||
setState(() {
|
setState(() {
|
||||||
_gps = LatLng(lat, lng);
|
_gps = Tuple2(lat, lng);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,7 +365,7 @@ class _ViewerDetailPaneState extends State<ViewerDetailPane> {
|
||||||
String _exposureTime;
|
String _exposureTime;
|
||||||
double _focalLength;
|
double _focalLength;
|
||||||
int _isoSpeedRatings;
|
int _isoSpeedRatings;
|
||||||
LatLng _gps;
|
Tuple2<double, double> _gps;
|
||||||
|
|
||||||
static final _log =
|
static final _log =
|
||||||
Logger("widget.viewer_detail_pane._ViewerDetailPaneState");
|
Logger("widget.viewer_detail_pane._ViewerDetailPaneState");
|
||||||
|
|
Loading…
Add table
Reference in a new issue