285 lines
11 KiB
Dart
285 lines
11 KiB
Dart
//import 'dart:async';
|
|
import 'dart:convert';
|
|
// 'dart:typed_data';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
// 'package:flutter/services.dart';
|
|
//import 'package:google_maps_flutter/google_maps_flutter.dart';
|
|
import 'package:manager_api_new/api.dart';
|
|
import 'package:mymuseum_visitapp/Models/visitContext.dart';
|
|
import 'package:mymuseum_visitapp/Helpers/translationHelper.dart';
|
|
import 'package:mymuseum_visitapp/Screens/Sections/Map/flutter_map_view.dart';
|
|
import 'package:mymuseum_visitapp/Screens/Sections/GuidedPath/guided_path_list_sheet.dart';
|
|
import 'package:mymuseum_visitapp/Screens/Sections/Map/geo_point_filter.dart';
|
|
import 'package:mymuseum_visitapp/Screens/Sections/Map/map_box_view.dart';
|
|
import 'package:mymuseum_visitapp/Screens/Sections/Map/marker_view.dart';
|
|
import 'package:mymuseum_visitapp/app_context.dart';
|
|
import 'package:mymuseum_visitapp/constants.dart';
|
|
import 'package:provider/provider.dart';
|
|
/*import 'package:tablet_app/Components/loading.dart';
|
|
import 'package:tablet_app/Components/loading_common.dart';*/
|
|
//import 'dart:ui' as ui;
|
|
import 'package:flutter/widgets.dart';
|
|
//import 'package:http/http.dart' as http;
|
|
|
|
import 'google_map_view.dart';
|
|
//import 'package:image/image.dart' as IMG;
|
|
|
|
//Set<Marker> markers = {};
|
|
List<GeoPointDTO> markersList = [];
|
|
|
|
class MapPage extends StatefulWidget {
|
|
final MapDTO section;
|
|
final List<Map<String, dynamic>> icons;
|
|
MapPage({Key? key, required this.section, required this.icons}) : super(key: key);
|
|
|
|
@override
|
|
_MapPage createState() => _MapPage();
|
|
}
|
|
|
|
class _MapPage extends State<MapPage> {
|
|
MapDTO? mapDTO;
|
|
late ValueNotifier<List<GeoPointDTO>> _geoPoints = ValueNotifier<List<GeoPointDTO>>([]);
|
|
bool _showListView = false;
|
|
|
|
/*Future<Uint8List> getBytesFromAsset(ByteData data, int width) async {
|
|
//ByteData data = await rootBundle.load(path);
|
|
ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List(),
|
|
targetWidth: width);
|
|
ui.FrameInfo fi = await codec.getNextFrame();
|
|
return (await fi.image.toByteData(format: ui.ImageByteFormat.png))
|
|
!.buffer
|
|
.asUint8List();
|
|
}*/
|
|
|
|
@override
|
|
void initState() {
|
|
//mapDTO = MapDTO.fromJson(jsonDecode(widget.section.data!));
|
|
mapDTO = widget.section;
|
|
_geoPoints.value = mapDTO!.points!;
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
// TODO: implement dispose
|
|
super.dispose();
|
|
}
|
|
|
|
/*static final CameraPosition _kLake = CameraPosition(
|
|
bearing: 192.8334901395799,
|
|
target: LatLng(37.43296265331129, -122.08832357078792),
|
|
tilt: 59.440717697143555,
|
|
zoom: 59.151926040649414);*/
|
|
|
|
Widget _buildListView(List<GeoPointDTO> points, VisitAppContext visitAppContext) {
|
|
if (points.isEmpty) {
|
|
return const Center(child: Text('Aucun point à afficher'));
|
|
}
|
|
return ListView.builder(
|
|
padding: const EdgeInsets.only(top: 80, bottom: 24),
|
|
itemCount: points.length,
|
|
itemBuilder: (_, i) {
|
|
final point = points[i];
|
|
final title = TranslationHelper.get(point.title, visitAppContext);
|
|
final desc = TranslationHelper.get(point.description, visitAppContext);
|
|
return ListTile(
|
|
leading: point.imageUrl != null
|
|
? ClipRRect(
|
|
borderRadius: BorderRadius.circular(8),
|
|
child: Image.network(
|
|
point.imageUrl!,
|
|
width: 48,
|
|
height: 48,
|
|
fit: BoxFit.cover,
|
|
errorBuilder: (_, __, ___) => const Icon(Icons.place, color: kMainColor, size: 32),
|
|
),
|
|
)
|
|
: const Icon(Icons.place, color: kMainColor, size: 32),
|
|
title: Text(title.isNotEmpty ? title : 'Point d\'intérêt'),
|
|
subtitle: desc.isNotEmpty
|
|
? Text(desc, maxLines: 2, overflow: TextOverflow.ellipsis)
|
|
: null,
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
//final mapContext = Provider.of<MapContext>(context);
|
|
final appContext = Provider.of<AppContext>(context);
|
|
VisitAppContext visitAppContext = appContext.getContext() as VisitAppContext;
|
|
|
|
var primaryColor = visitAppContext.configuration != null ? visitAppContext.configuration!.primaryColor != null ? Color(int.parse(visitAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16)) : kSecondColor : kSecondColor;
|
|
|
|
/*return FutureBuilder(
|
|
future: getByteIcon(mapDTO!.iconSource),
|
|
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
|
if (snapshot.connectionState == ConnectionState.done) {
|
|
} else if (snapshot.connectionState == ConnectionState.none) {
|
|
return Text("No data");
|
|
} else {
|
|
return Center(
|
|
child: Container(
|
|
child: LoadingCommon()
|
|
)
|
|
);
|
|
}
|
|
}
|
|
);*/
|
|
return MediaQuery.removeViewInsets(
|
|
context: context,
|
|
removeBottom: true,
|
|
child: Stack(
|
|
fit: StackFit.passthrough,
|
|
children: <Widget>[
|
|
ValueListenableBuilder<List<GeoPointDTO>>(
|
|
valueListenable: _geoPoints,
|
|
builder: (context, value, _) {
|
|
if (_showListView) {
|
|
return _buildListView(value, visitAppContext);
|
|
}
|
|
switch(mapDTO!.mapProvider) {
|
|
case MapProvider.Google:
|
|
return GoogleMapView(language: appContext.getContext().language, geoPoints: value, mapDTO: mapDTO!, icons: widget.icons);
|
|
case MapProvider.MapBox:
|
|
return MapBoxView(language: appContext.getContext().language, geoPoints: value, mapDTO: mapDTO, icons: widget.icons);
|
|
default:
|
|
return GoogleMapView(language: appContext.getContext().language, geoPoints: value, mapDTO: mapDTO!, icons: widget.icons);
|
|
}
|
|
}
|
|
),
|
|
GeoPointFilter(
|
|
language: visitAppContext.language!,
|
|
geoPoints: mapDTO!.points!,
|
|
categories: mapDTO!.categories!,
|
|
provider: mapDTO!.mapProvider == null ? MapProvider.Google : mapDTO!.mapProvider!,
|
|
filteredPoints: (value) {
|
|
_geoPoints.value = value!;
|
|
}),
|
|
if (!_showListView) MarkerViewWidget(),
|
|
Positioned(
|
|
top: 35,
|
|
left: 10,
|
|
child: SizedBox(
|
|
width: 50,
|
|
height: 50,
|
|
child: InkWell(
|
|
onTap: () {
|
|
Navigator.of(context).pop();
|
|
},
|
|
child: Container(
|
|
decoration: BoxDecoration(
|
|
color: primaryColor,
|
|
shape: BoxShape.circle,
|
|
),
|
|
child: const Icon(Icons.arrow_back, size: 23, color: Colors.white)
|
|
),
|
|
)
|
|
),
|
|
),
|
|
if (mapDTO?.guidedPaths?.isNotEmpty == true)
|
|
Positioned(
|
|
top: 35,
|
|
right: 10,
|
|
child: InkWell(
|
|
onTap: () {
|
|
showModalBottomSheet(
|
|
context: context,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
|
|
),
|
|
builder: (_) => GuidedPathListSheet(
|
|
paths: mapDTO!.guidedPaths!,
|
|
mapDTO: mapDTO!,
|
|
visitAppContext: visitAppContext,
|
|
),
|
|
);
|
|
},
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
|
|
decoration: BoxDecoration(
|
|
color: primaryColor,
|
|
borderRadius: BorderRadius.circular(25),
|
|
),
|
|
child: const Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(Icons.route, size: 18, color: Colors.white),
|
|
SizedBox(width: 6),
|
|
Text('Parcours', style: TextStyle(color: Colors.white, fontWeight: FontWeight.w500)),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
if (mapDTO?.isListViewEnabled == true)
|
|
Positioned(
|
|
bottom: 24,
|
|
right: 16,
|
|
child: GestureDetector(
|
|
onTap: () => setState(() => _showListView = !_showListView),
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
|
|
decoration: BoxDecoration(
|
|
color: primaryColor,
|
|
borderRadius: BorderRadius.circular(25),
|
|
boxShadow: const [BoxShadow(color: Colors.black26, blurRadius: 6, offset: Offset(0, 2))],
|
|
),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(_showListView ? Icons.map_outlined : Icons.list, size: 18, color: Colors.white),
|
|
const SizedBox(width: 6),
|
|
Text(
|
|
_showListView ? 'Carte' : 'Liste',
|
|
style: const TextStyle(color: Colors.white, fontWeight: FontWeight.w500),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
]
|
|
/*floatingActionButton: FloatingActionButton.extended(
|
|
onPressed: _goToTheLake,
|
|
label: Text('To the lake!'),
|
|
icon: Icon(Icons.directions_boat),
|
|
),*/
|
|
),
|
|
);
|
|
}
|
|
|
|
/*getByteIcon(String? source) async {
|
|
if(source != null) {
|
|
if(kIsWeb) {
|
|
Uint8List fileData = await http.readBytes(Uri.parse(source));
|
|
selectedMarkerIcon = resizeImage(fileData, 40);
|
|
} else {
|
|
final ByteData imageData = await NetworkAssetBundle(Uri.parse(source)).load("");
|
|
selectedMarkerIcon = await getBytesFromAsset(imageData, 50);
|
|
}
|
|
} else {
|
|
// default icon
|
|
final ByteData bytes = await rootBundle.load('assets/icons/marker.png');
|
|
selectedMarkerIcon = await getBytesFromAsset(bytes, 25);
|
|
}
|
|
}*/
|
|
|
|
/*Uint8List resizeImage(Uint8List data, int width) {
|
|
Uint8List resizedData = data;
|
|
IMG.Image img = IMG.decodeImage(data)!;
|
|
IMG.Image resized = IMG.copyResize(img, width: width);
|
|
resizedData = Uint8List.fromList(IMG.encodeJpg(resized));
|
|
return resizedData;
|
|
}*/
|
|
|
|
/*Future<void> _goToTheLake() async {
|
|
final GoogleMapController controller = await _controller.future;
|
|
controller.animateCamera(CameraUpdate.newCameraPosition(_kLake));
|
|
}*/
|
|
|
|
}
|
|
|