693 lines
39 KiB
Dart

import 'package:auto_size_text/auto_size_text.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:manager_api_new/api.dart';
import 'package:mymuseum_visitapp/Components/loading_common.dart';
import 'package:mymuseum_visitapp/Components/show_element_for_resource.dart';
import 'package:mymuseum_visitapp/Helpers/ImageCustomProvider.dart';
import 'package:mymuseum_visitapp/Models/visitContext.dart';
import 'package:mymuseum_visitapp/app_context.dart';
import 'package:photo_view/photo_view.dart';
import 'package:provider/provider.dart';
import 'package:html/parser.dart' show parse;
import 'package:qr_flutter/qr_flutter.dart';
import '../../../constants.dart';
import 'map_context.dart';
class MarkerViewWidget extends StatefulWidget {
MarkerViewWidget();
@override
_MarkerInfoWidget createState() => _MarkerInfoWidget();
}
class _MarkerInfoWidget extends State<MarkerViewWidget> {
CarouselSliderController? sliderController;
ValueNotifier<int> currentIndex = ValueNotifier<int>(1);
@override
void initState() {
sliderController = CarouselSliderController();
super.initState();
}
@override
void dispose() {
sliderController = null;
super.dispose();
}
@override
Widget build(BuildContext context) {
int breakPointPrice = 50;
Size size = MediaQuery.of(context).size;
final mapContext = Provider.of<MapContext>(context);
final appContext = Provider.of<AppContext>(context);
VisitAppContext visitAppContext = appContext.getContext() as VisitAppContext;
var language = visitAppContext.language;
GeoPointDTO? selectedPoint = mapContext.getSelectedPoint() as GeoPointDTO?;
ScrollController scrollDescription = new ScrollController();
ScrollController scrollPrice = new ScrollController();
var isPointPrice = selectedPoint != null && selectedPoint.prices != null && selectedPoint.prices!.isNotEmpty && selectedPoint.prices!.any((d) => d.language == language) && selectedPoint.prices!.firstWhere((d) => d.language == language).value != null && selectedPoint.prices!.firstWhere((d) => d.language == language).value!.trim().length > 0;
Color primaryColor = new Color(int.parse(visitAppContext.configuration!.primaryColor!.split('(0x')[1].split(')')[0], radix: 16));
Size sizeMarker = Size(size.width * 0.93, size.height * 0.83);
return Center(
child: Visibility(
visible: selectedPoint != null,
child: Container(
width: sizeMarker.width,
height: sizeMarker.height,
margin: EdgeInsets.symmetric(vertical: 3, horizontal: 4),
decoration: BoxDecoration(
color: kBackgroundColor, // Colors.amberAccent //kBackgroundLight,
//shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
/*boxShadow: [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.5,
blurRadius: 1.1,
offset: Offset(0, 1.1), // changes position of shadow
),
],*/
),
child: Stack(
children: <Widget> [
Positioned(
right: 5,
top: 5,
child: InkWell(
onTap: () {
setState(() {
mapContext.setSelectedPoint(null);
mapContext.setSelectedPointForNavigate(null);
});
},
child: Container(
width: 50,
height: 50,
decoration: BoxDecoration(
color: kBackgroundGrey,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: kBackgroundGrey,
spreadRadius: 0.5,
blurRadius: 1.1,
offset: Offset(0, 1.1), // changes position of shadow
),
],
),
child: Icon(
Icons.close,
size: 25,
color: Colors.white,
),
),
),
),
if(selectedPoint != null)
Row(
children: [
selectedPoint.imageResourceId != null && selectedPoint.imageUrl != null ? ClipRRect(
borderRadius: BorderRadius.only(topLeft: Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 20.0), bottomLeft: Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
child: Container(
child: Center(
child: Container(
decoration: BoxDecoration(
border: Border(right: BorderSide(width: 0.05, color: kMainGrey)),
color: Colors.grey,
),
width: size.width * 0.17,
height: size.height,
child: CachedNetworkImage(
imageUrl: selectedPoint.imageUrl!,
width: size.width,
fit: BoxFit.cover,
progressIndicatorBuilder: (context, url, downloadProgress) {
return Center(
child: SizedBox(
width: 50,
height: 50,
child: LoadingCommon(),
),
);
},
errorWidget: (context, url, error) => Icon(Icons.error),
),
),
)
),
): SizedBox(),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.only(top: 8.0, left: 15.0),
child: Container(
//color: Colors.green,
height: size.height * 0.06,
width: size.width * 0.65,
child: HtmlWidget(
selectedPoint.title!.firstWhere((t) => t.language == language).value!,
textStyle: TextStyle(fontSize: 20.0),
),
),
),
Row(
//mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.only(left: 15),
child: Column(
children: [
Container(
height: isPointPrice && selectedPoint.prices!.firstWhere((d) => d.language == language).value!.length > breakPointPrice ? size.height * 0.50 : size.height * 0.7,
width: size.width * 0.38,
decoration: BoxDecoration(
color: kBackgroundLight,
borderRadius: BorderRadius.all(Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
),
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 10, bottom: 10, top: 15),
child: Scrollbar(
controller: scrollDescription,
thumbVisibility: true,
thickness: 2.0,
child: SingleChildScrollView(
controller: scrollDescription,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if(selectedPoint.description!.any((d) => d.language == language) && selectedPoint.description!.firstWhere((d) => d.language == language).value != null && selectedPoint.description!.firstWhere((d) => d.language == language).value!.trim().length > 0)
HtmlWidget(
selectedPoint.description!.firstWhere((d) => d.language == language).value!,
customStylesBuilder: (element) {
return {'text-align': 'left', 'font-family': "Roboto"};
},
textStyle: TextStyle(fontSize: kDescriptionSize),
),
],
),
),
),
),
),
),
if(isPointPrice && selectedPoint.prices!.firstWhere((d) => d.language == language).value!.length > breakPointPrice)
Container(
height: size.height * 0.20,
width: size.width * 0.38,
decoration: BoxDecoration(
color: kBackgroundLight,
borderRadius: BorderRadius.all(Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
),
child: Padding(
padding: const EdgeInsets.only(left: 20, right: 10, bottom: 10, top: 15),
child: Scrollbar(
controller: scrollPrice,
thumbVisibility: true,
thickness: 2.0,
child: SingleChildScrollView(
controller: scrollPrice,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
//crossAxisAlignment: CrossAxisAlignment.center,
//mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Center(child: Padding(
padding: const EdgeInsets.all(5.0),
child: Icon(Icons.price_change_outlined, color: primaryColor, size: 25),
)),
HtmlWidget(
selectedPoint.prices!.firstWhere((d) => d.language == language).value!,
customStylesBuilder: (element) {
return {'text-align': 'left', 'font-family': "Roboto"};
},
textStyle: TextStyle(fontSize: kDescriptionSize),
),
],
),
),
),
),
),
),
],
),
),
SizedBox(
width: size.width * 0.32,
height: size.height * 0.7,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
//color: Colors.green,
height: size.height * 0.35,
child: CarouselSlider(
carouselController: sliderController,
options: CarouselOptions(
onPageChanged: (int index, CarouselPageChangedReason reason) {
currentIndex.value = index + 1;
},
height: size.height *0.33,
enlargeCenterPage: true,
pageSnapping: true,
reverse: false,
),
items: selectedPoint.contents!.map<Widget>((ContentDTO i) {
return Builder(
builder: (BuildContext context) {
AppContext appContext = Provider.of<AppContext>(context);
var resourcetoShow = getElementForResource(context, appContext, i, true);
return resourcetoShow;
},
);
}).toList(),
),
),
Container(
//color: Colors.yellow,
height: size.height * 0.33,
child: Padding(
padding: const EdgeInsets.only(top: 10.0),
child: Column(
children: [
/*if(isPointPrice && selectedPoint.prices!.firstWhere((d) => d.language == language).value!.length > breakPointPrice)
Container(
height: size.height * 0.1,
width: size.width * 0.38,
decoration: BoxDecoration(
color: kBackgroundLight,
borderRadius: BorderRadius.all(Radius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
),
child: Padding(
padding: EdgeInsets.all(5),
child: Scrollbar(
thumbVisibility: true,
thickness: 2.0,
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(5.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
// todo add width ?
Padding(
padding: const EdgeInsets.all(5.0),
child: Icon(Icons.price_change_outlined, color: primaryColor, size: 13),
),
HtmlWidget(
selectedPoint.prices!.firstWhere((d) => d.language == language).value!,
customStylesBuilder: (element) {
return {'text-align': 'left', 'font-family': "Roboto"};
},
textStyle: TextStyle(fontSize: 12),
),
],
),
),
),
),
),
),*/
if(isPointPrice && selectedPoint.prices!.firstWhere((d) => d.language == language).value!.length <= breakPointPrice)
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Icon(Icons.price_change_outlined, color: primaryColor, size: 13),
Padding(
padding: const EdgeInsets.all(4.0),
child: HtmlWidget(
selectedPoint.prices!.firstWhere((d) => d.language == language).value!,
customStylesBuilder: (element) {
return {'text-align': 'left', 'font-family': "Roboto"};
},
textStyle: TextStyle(fontSize: 12),
),
)
],
),
selectedPoint.phone != null && selectedPoint.phone!.isNotEmpty && selectedPoint.phone!.any((d) => d.language == language) && selectedPoint.phone!.firstWhere((d) => d.language == language).value != null && selectedPoint.phone!.firstWhere((d) => d.language == language).value!.trim().length > 0 ? Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Icon(Icons.phone, color: primaryColor, size: 13),
Padding(
padding: const EdgeInsets.all(4.0),
child: Text(parse(selectedPoint.phone!.firstWhere((p) => p.language == language).value!).documentElement!.text, style: TextStyle(fontSize: 12)),
)
],
): SizedBox(),
selectedPoint.email != null && selectedPoint.email!.isNotEmpty && selectedPoint.email!.any((d) => d.language == language) && selectedPoint.email!.firstWhere((d) => d.language == language).value != null && selectedPoint.email!.firstWhere((d) => d.language == language).value!.trim().length > 0 ? Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Icon(Icons.email, color: primaryColor, size: 13),
Padding(
padding: const EdgeInsets.all(4.0),
child: SizedBox(
width: size.width*0.25,
child: AutoSizeText(parse(selectedPoint.email!.firstWhere((p) => p.language == language).value!).documentElement!.text, style: TextStyle(fontSize: 12), maxLines: 3)
),
)
],
): SizedBox(),
selectedPoint.site != null && selectedPoint.site!.isNotEmpty && selectedPoint.site!.any((d) => d.language == language) && selectedPoint.site!.firstWhere((d) => d.language == language).value != null && selectedPoint.site!.firstWhere((d) => d.language == language).value!.trim().length > 0 ? Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Icon(Icons.public, color: primaryColor, size: 13),
Padding(
padding: const EdgeInsets.all(4.0),
child: SizedBox(
width: size.width*0.25,
child: AutoSizeText(parse(selectedPoint.site!.firstWhere((p) => p.language == language).value!).documentElement!.text, style: TextStyle(fontSize: 12), maxLines: 3)
),
)
],
): SizedBox(),
selectedPoint.site != null && selectedPoint.site!.isNotEmpty && selectedPoint.site!.any((d) => d.language == language) && selectedPoint.site!.firstWhere((d) => d.language == language).value != null && selectedPoint.site!.firstWhere((d) => d.language == language).value!.trim().length > 0 ? Expanded(
child: Center(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Container(
width: size.width *0.1,
height: 120,
child: QrImageView(
padding: EdgeInsets.only(left: 5.0, top: 5.0, bottom: 5.0, right: 5.0),
data: parse(selectedPoint.site!.firstWhere((p) => p.language == language).value!).documentElement!.text,
version: QrVersions.auto,
size: 50.0,
),
),
),
),
): SizedBox(),
],
),
),
),
],
),
),
)
],
)
],
),
],
),
/*Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.only(top: 20),
child: HtmlWidget(
(mapContext.getSelectedMarker() as MapMarker).title!,
customStylesBuilder: (element) {
return {'text-align': 'center'};
},
textStyle: TextStyle(fontWeight: FontWeight.w500, fontSize: kIsWeb ? kWebTitleSize : kTitleSize)
),
),
),
Padding(
padding: const EdgeInsets.only(top: 75),
child: Center(
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if((mapContext.getSelectedMarker() as MapMarker).contents != null && (mapContext.getSelectedMarker() as MapMarker).contents!.length > 0)
Stack(
children: [
Container(
//color: Colors.green,
child: CarouselSlider(
carouselController: sliderController,
options: CarouselOptions(
onPageChanged: (int index, CarouselPageChangedReason reason) {
currentIndex.value = index + 1;
},
height: size.height *0.35,
enlargeCenterPage: true,
pageSnapping: true,
reverse: false,
),
items: (mapContext.getSelectedMarker() as MapMarker).contents!.map<Widget>((ContentGeoPoint i) {
return Builder(
builder: (BuildContext context) {
AppContext appContext = Provider.of<AppContext>(context);
var resourcetoShow = getElementForResource(context, appContext, i);
return Padding(
padding: const EdgeInsets.all(8.0),
child: resourcetoShow,
);
},
);
}).toList(),
),
),
Positioned(
bottom: 0,
child: Container(
//color: Colors.red,
height: 25,
width: sizeMarker.width,
//color: Colors.amber,
child: Padding(
padding: const EdgeInsets.only(top: 0),
child: Align(
alignment: Alignment.bottomCenter,
child: ValueListenableBuilder<int>(
valueListenable: currentIndex,
builder: (context, value, _) {
return Text(
value.toString()+'/'+(mapContext.getSelectedMarker() as MapMarker).contents!.length.toString(),
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
);
}
)
),
),
),
),
],
),
// Description
Container(
height: (mapContext.getSelectedMarker() as MapMarker).contents != null && (mapContext.getSelectedMarker() as MapMarker).contents!.length > 0 ? size.height *0.3 : size.height *0.6,
width: MediaQuery.of(context).size.width *0.4,
decoration: BoxDecoration(
color: kBackgroundColor,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(tabletAppContext.configuration!.roundedValue?.toDouble() ?? 10.0),
boxShadow: [
BoxShadow(
color: kBackgroundSecondGrey,
spreadRadius: 0.5,
blurRadius: 1.1,
offset: Offset(0, 1.1), // changes position of shadow
),
],
),
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(15.0),
child: HtmlWidget(
(mapContext.getSelectedMarker() as MapMarker).description!,
customStylesBuilder: (element) {
return {'text-align': 'center'};
},
textStyle: TextStyle(fontSize: kIsWeb ? kWebDescriptionSize : kDescriptionSize)
),
),
),
),
]
),
if((mapContext.getSelectedMarker() as MapMarker).contents != null && (mapContext.getSelectedMarker() as MapMarker).contents!.length > 1)
Positioned(
top: MediaQuery.of(context).size.height * 0.125,
right: -10,
child: InkWell(
onTap: () {
if ((mapContext.getSelectedMarker() as MapMarker).contents!.length > 0)
sliderController!.nextPage(duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
},
child: Icon(
Icons.chevron_right,
size: kIsWeb ? 100 : 85,
color: kTestSecondColor,
),
)
),
if((mapContext.getSelectedMarker() as MapMarker).contents != null && (mapContext.getSelectedMarker() as MapMarker).contents!.length > 1)
Positioned(
top: MediaQuery.of(context).size.height * 0.125,
left: -10,
child: InkWell(
onTap: () {
if ((mapContext.getSelectedMarker() as MapMarker).contents!.length > 0)
sliderController!.previousPage(duration: new Duration(milliseconds: 500), curve: Curves.fastOutSlowIn);
},
child: Icon(
Icons.chevron_left,
size: kIsWeb ? 100 : 85,
color: kTestSecondColor,
),
)
),
],
),
),
),*/
])
),
),
);
}
}
getElementForResource(BuildContext context, AppContext appContext, ContentDTO i, bool addFullScreen) {
var widgetToInclude;
Size size = MediaQuery.of(context).size;
VisitAppContext visitAppContext = appContext.getContext() as VisitAppContext;
switch(i.resource?.type) {
case ResourceType.Image:
case ResourceType.ImageUrl:
widgetToInclude = GestureDetector(
onTap: () {
if(addFullScreen) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
),
contentPadding: EdgeInsets.zero,
// title: Text(eventAgenda.name!),
content: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
color: kBackgroundColor,
),
height: size.height * 0.8,
width: size.width * 0.8,
child: Container(
decoration: BoxDecoration(
//color: Colors.yellow,
borderRadius: BorderRadius.all(Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 15.0)),
),
child: PhotoView(
imageProvider: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resource!.url!),
minScale: PhotoViewComputedScale.contained * 0.8,
maxScale: PhotoViewComputedScale.contained * 3.0,
backgroundDecoration: BoxDecoration(
color: kBackgroundGrey,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 15.0),
),
),
),
),
);
},
);
}
},
child: Container(
decoration: BoxDecoration(
//color: kBackgroundLight,
image: DecorationImage(
image: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resource!.url!),
fit: BoxFit.cover,
),
borderRadius: BorderRadius.all(Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 15.0)),
/*border: Border.all(
color: kBackgroundGrey,
width: 1.0,
),*/
),
),
);
break;
case ResourceType.Video:
case ResourceType.VideoUrl:
case ResourceType.Audio:
widgetToInclude = GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
if(addFullScreen && i.resource!.type != ResourceType.Audio) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 20.0))
),
contentPadding: EdgeInsets.zero,
// title: Text(eventAgenda.name!),
content: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 20.0)),
color: kBackgroundColor,
),
height: size.height * 0.8,
width: size.width * 0.8,
child: Center(child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resource?.url, type: i.resource?.type), appContext, false, true)),
),
);
},
);
}
},
child: IgnorePointer(
ignoring: i.resource!.type != ResourceType.Audio,
child: Container(
decoration: BoxDecoration(
color: Colors.yellow,
shape: BoxShape.rectangle,
borderRadius: BorderRadius.circular(visitAppContext.configuration!.roundedValue?.toDouble() ?? 15.0),
),
child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resource?.url, type: i.resource?.type), appContext, false, true),
),
),
);
break;
}
return Center(
child: Container(
height: MediaQuery.of(context).size.height * 0.6,
width: MediaQuery.of(context).size.width * 0.72,
child: AspectRatio(
aspectRatio: 16 / 9,
child: ClipRect(
child: widgetToInclude,
),
),
),
);
}