mirror of
https://bitbucket.org/FransoletThomas/tablet-app.git
synced 2025-12-06 08:31:19 +00:00
add MapBox Agenda + updated quiz (full screen + confetti)
This commit is contained in:
parent
c8224b1e35
commit
378c431762
@ -6,6 +6,7 @@ import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:manager_api/api.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tablet_app/Components/loading_common.dart';
|
||||
@ -30,6 +31,7 @@ class _AgendaView extends State<AgendaView> {
|
||||
AgendaDTO agendaDTO = AgendaDTO();
|
||||
late Agenda agenda;
|
||||
late ValueNotifier<List<EventAgenda>> filteredAgenda = ValueNotifier<List<EventAgenda>>([]);
|
||||
late Uint8List mapIcon;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -61,6 +63,9 @@ class _AgendaView extends State<AgendaView> {
|
||||
agenda.events = agenda.events.where((a) => a.dateFrom!.isAfter(DateTime.now())).toList();
|
||||
agenda.events.sort((a, b) => a.dateFrom!.compareTo(b.dateFrom!));
|
||||
filteredAgenda.value = agenda.events;
|
||||
|
||||
mapIcon = await getByteIcon();
|
||||
|
||||
return agenda;
|
||||
} catch(e) {
|
||||
print("Erreur lors du parsing du json : ${e.toString()}");
|
||||
@ -68,6 +73,22 @@ class _AgendaView extends State<AgendaView> {
|
||||
}
|
||||
}
|
||||
|
||||
getByteIcon() async {
|
||||
final ByteData bytes = await rootBundle.load('assets/icons/marker.png');
|
||||
var icon = await getBytesFromAsset(bytes, 25);
|
||||
return icon;
|
||||
}
|
||||
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
@ -134,7 +155,7 @@ class _AgendaView extends State<AgendaView> {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return EventPopup(eventAgenda: eventAgenda, mapProvider: agendaDTO.mapProvider ?? MapProvider.Google);
|
||||
return EventPopup(eventAgenda: eventAgenda, mapProvider: agendaDTO.mapProvider ?? MapProvider.Google, mapIcon: mapIcon);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
@ -21,8 +21,9 @@ import 'dart:ui' as ui;
|
||||
class EventPopup extends StatefulWidget {
|
||||
final EventAgenda eventAgenda;
|
||||
final MapProvider mapProvider;
|
||||
final Uint8List mapIcon;
|
||||
|
||||
EventPopup({Key? key, required this.eventAgenda, required this.mapProvider}) : super(key: key);
|
||||
EventPopup({Key? key, required this.eventAgenda, required this.mapProvider, required this.mapIcon}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<EventPopup> createState() => _EventPopupState();
|
||||
@ -60,7 +61,7 @@ class _EventPopupState extends State<EventPopup> {
|
||||
|
||||
mapboxMap.annotations.createPointAnnotationManager().then((pointAnnotationManager) async {
|
||||
this.pointAnnotationManager = pointAnnotationManager;
|
||||
pointAnnotationManager.createMulti(createPoints(LatLng(widget.eventAgenda.address!.lat, widget.eventAgenda.address!.lng), icon));
|
||||
pointAnnotationManager.createMulti(createPoints(LatLng(double.parse(widget.eventAgenda.address!.lat!.toString()), double.parse(widget.eventAgenda.address!.lng!.toString())), icon));
|
||||
init = true;
|
||||
});
|
||||
}
|
||||
@ -85,21 +86,7 @@ class _EventPopupState extends State<EventPopup> {
|
||||
return options;
|
||||
}
|
||||
|
||||
getByteIcon() async {
|
||||
final ByteData bytes = await rootBundle.load('assets/icons/marker.png');
|
||||
var icon = await getBytesFromAsset(bytes, 25);
|
||||
return icon;
|
||||
}
|
||||
|
||||
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
|
||||
Widget build(BuildContext context) {
|
||||
@ -301,32 +288,16 @@ class _EventPopupState extends State<EventPopup> {
|
||||
},
|
||||
markers: markers,
|
||||
) :
|
||||
FutureBuilder(
|
||||
future: getByteIcon(),
|
||||
builder: (context, AsyncSnapshot<dynamic> snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.done) {
|
||||
Uint8List icon = snapshot.data!;
|
||||
return mapBox.MapWidget(
|
||||
mapBox.MapWidget(
|
||||
key: ValueKey("mapBoxWidget"),
|
||||
styleUri: mapBox.MapboxStyles.STANDARD,
|
||||
onMapCreated: (maBoxMap) {
|
||||
_onMapCreated(maBoxMap, icon);
|
||||
_onMapCreated(maBoxMap, widget.mapIcon);
|
||||
},
|
||||
cameraOptions: mapBox.CameraOptions(
|
||||
center: mapBox.Point(coordinates: mapBox.Position(double.parse(widget.eventAgenda.address!.lng!.toString()), double.parse(widget.eventAgenda.address!.lat!.toString()))).toJson(),
|
||||
zoom: 14
|
||||
),
|
||||
);
|
||||
} else if (snapshot.connectionState == ConnectionState.none) {
|
||||
return Text("No data");
|
||||
} else {
|
||||
return Center(
|
||||
child: Container(
|
||||
child: LoadingCommon()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
),
|
||||
): SizedBox(),
|
||||
SizedBox(
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import 'dart:math';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Path drawStrawberry(Size size) {
|
||||
// Method to convert degree to radians
|
||||
double degToRad(double deg) => deg * (pi / 180.0);
|
||||
@ -120,3 +122,62 @@ Path drawStrawberry(Size size) {
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
Path drawStar(Size size) {
|
||||
// Méthode pour convertir les degrés en radians
|
||||
double degToRad(double deg) => deg * (pi / 180.0);
|
||||
|
||||
// Nombre de pointes de l'étoile
|
||||
const numberOfPoints = 5;
|
||||
|
||||
// Variables pour les dimensions de l'étoile
|
||||
final halfWidth = size.width / 2;
|
||||
final externalRadius = halfWidth;
|
||||
final internalRadius = halfWidth / 2.5;
|
||||
final degreesPerStep = degToRad(360 / numberOfPoints);
|
||||
final halfDegreesPerStep = degreesPerStep / 2;
|
||||
|
||||
// Création du chemin pour dessiner l'étoile
|
||||
var path = Path();
|
||||
|
||||
// Début du dessin de l'étoile
|
||||
path.moveTo(size.width, halfWidth);
|
||||
|
||||
// Boucle pour dessiner chaque pointe de l'étoile
|
||||
for (double step = 0; step < 2 * pi; step += degreesPerStep) {
|
||||
// Pointe externe de l'étoile
|
||||
path.lineTo(halfWidth + externalRadius * cos(step),
|
||||
halfWidth + externalRadius * sin(step));
|
||||
|
||||
// Pointe interne de l'étoile
|
||||
path.lineTo(halfWidth + internalRadius * cos(step + halfDegreesPerStep),
|
||||
halfWidth + internalRadius * sin(step + halfDegreesPerStep));
|
||||
}
|
||||
|
||||
// Fermeture du chemin
|
||||
path.close();
|
||||
|
||||
// Retourne le chemin complet de l'étoile
|
||||
return path;
|
||||
}
|
||||
|
||||
Path drawText(String text) {
|
||||
final painter = TextPainter(
|
||||
text: TextSpan(text: text, style: TextStyle()),
|
||||
textDirection: TextDirection.ltr,
|
||||
);
|
||||
|
||||
painter.layout();
|
||||
|
||||
final textWidth = painter.width;
|
||||
final textHeight = painter.height;
|
||||
|
||||
final offsetX = (50 - textWidth) / 2;
|
||||
final offsetY = (50 - textHeight) / 2;
|
||||
|
||||
final path = Path();
|
||||
path.addRect(Rect.fromLTWH(offsetX, offsetY, textWidth, textHeight));
|
||||
path.close();
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
|
||||
import 'package:manager_api/api.dart';
|
||||
import 'package:photo_view/photo_view.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:tablet_app/Components/Buttons/rounded_button.dart';
|
||||
import 'package:tablet_app/Components/show_element_for_resource.dart';
|
||||
@ -100,17 +101,19 @@ class _QuizzView extends State<QuizzView> {
|
||||
height: 5,
|
||||
child: ConfettiWidget(
|
||||
confettiController: _controllerCenter!,
|
||||
numberOfParticles: 2,
|
||||
blastDirectionality: BlastDirectionality.explosive,
|
||||
shouldLoop: false, // start again as soon as the animation is finished
|
||||
colors: const [
|
||||
Colors.red,
|
||||
kMainRed,
|
||||
kSecondRed
|
||||
Colors.blueGrey,
|
||||
Colors.green,
|
||||
kTestSecondColor
|
||||
//Colors.pink,
|
||||
//Colors.orange,
|
||||
//Colors.purple
|
||||
], // manually specify the colors to be used
|
||||
createParticlePath: drawStrawberry, // define a custom shape/path.
|
||||
createParticlePath: drawStar, // define a custom shape/path.
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -123,7 +126,7 @@ class _QuizzView extends State<QuizzView> {
|
||||
maxWidth: kIsWeb ? size.width * 0.20 : size.width * 0.20, //size.width * 0.25
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child : getElementForResource(context, appContext, levelToShow.label!.firstWhere((translation) => translation.language == appContext.getContext().language)),
|
||||
child : getElementForResource(context, appContext, levelToShow.label!.firstWhere((translation) => translation.language == appContext.getContext().language), true),
|
||||
),
|
||||
Container(
|
||||
height: 90,
|
||||
@ -337,7 +340,7 @@ class _QuizzView extends State<QuizzView> {
|
||||
alignment: Alignment.center,
|
||||
child : Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: getElementForResource(context, appContext, i.label!.firstWhere((translation) => translation.language == appContext.getContext().language)),
|
||||
child: getElementForResource(context, appContext, i.label!.firstWhere((translation) => translation.language == appContext.getContext().language), true),
|
||||
)
|
||||
),
|
||||
Padding(
|
||||
@ -411,7 +414,7 @@ class _QuizzView extends State<QuizzView> {
|
||||
alignment: Alignment.center,
|
||||
child : Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: getElementForResource(context, appContext, i.responsesSubDTO![index].label!.firstWhere((translation) => translation.language == appContext.getContext().language)),
|
||||
child: getElementForResource(context, appContext, i.responsesSubDTO![index].label!.firstWhere((translation) => translation.language == appContext.getContext().language), true),
|
||||
)
|
||||
),
|
||||
Container(
|
||||
@ -520,14 +523,55 @@ class _QuizzView extends State<QuizzView> {
|
||||
}
|
||||
}
|
||||
|
||||
getElementForResource(BuildContext context, AppContext appContext, TranslationAndResourceDTO i) {
|
||||
getElementForResource(BuildContext context, AppContext appContext, TranslationAndResourceDTO i, bool addFullScreen) {
|
||||
var widgetToInclude;
|
||||
Size size = MediaQuery.of(context).size;
|
||||
|
||||
switch(i.resourceType) {
|
||||
case ResourceType.Image:
|
||||
case ResourceType.ImageUrl:
|
||||
widgetToInclude = Container(
|
||||
//borderRadius: BorderRadius.all(Radius.circular(25.0)),
|
||||
widgetToInclude = GestureDetector(
|
||||
onTap: () {
|
||||
if(addFullScreen) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20.0))
|
||||
),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
// title: Text(eventAgenda.name!),
|
||||
content: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20.0)),
|
||||
color: kBackgroundColor,
|
||||
),
|
||||
height: size.height * 0.8,
|
||||
width: size.width * 0.8,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xff7c94b6),
|
||||
borderRadius: BorderRadius.all(Radius.circular(15.0)),
|
||||
),
|
||||
child: PhotoView(
|
||||
imageProvider: ImageCustomProvider.getImageProvider(appContext, i.resourceId!, i.resourceUrl!),
|
||||
minScale: PhotoViewComputedScale.contained * 0.8,
|
||||
maxScale: PhotoViewComputedScale.contained * 3.0,
|
||||
backgroundDecoration: BoxDecoration(
|
||||
color: kBackgroundSecondGrey,
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: BorderRadius.circular(15.0),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xff7c94b6),
|
||||
image: DecorationImage(
|
||||
@ -540,18 +584,50 @@ getElementForResource(BuildContext context, AppContext appContext, TranslationAn
|
||||
width: 1.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
break;
|
||||
case ResourceType.Video:
|
||||
case ResourceType.VideoUrl:
|
||||
case ResourceType.Audio:
|
||||
widgetToInclude = Container(
|
||||
widgetToInclude = GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onTap: () {
|
||||
if(addFullScreen && i.resourceType != ResourceType.Audio) {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
shape: const RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20.0))
|
||||
),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
// title: Text(eventAgenda.name!),
|
||||
content: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20.0)),
|
||||
color: kBackgroundColor,
|
||||
),
|
||||
height: size.height * 0.8,
|
||||
width: size.width * 0.8,
|
||||
child: Center(child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resourceUrl, type: i.resourceType), appContext, false, true)),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
},
|
||||
child: IgnorePointer(
|
||||
ignoring: i.resourceType != ResourceType.Audio,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: kBackgroundSecondGrey,
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: BorderRadius.circular(15.0),
|
||||
),
|
||||
child: showElementForResource(ResourceDTO(id: i.resourceId, url: i.resourceUrl, type: i.resourceType), appContext, false, true),
|
||||
),
|
||||
),
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user