200 lines
7.6 KiB
Dart

import 'dart:async';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:manager_api_new/api.dart';
import 'package:mymuseum_visitapp/Components/loading_common.dart';
import 'package:mymuseum_visitapp/Models/agenda.dart';
import 'package:mymuseum_visitapp/Models/visitContext.dart';
import 'package:mymuseum_visitapp/Screens/Sections/Agenda/event_list_item.dart';
import 'package:mymuseum_visitapp/Screens/Sections/Agenda/event_popup.dart';
import 'package:mymuseum_visitapp/Screens/Sections/Agenda/month_filter.dart';
import 'package:mymuseum_visitapp/app_context.dart';
import 'package:mymuseum_visitapp/constants.dart';
import 'package:provider/provider.dart';
class AgendaPage extends StatefulWidget {
final AgendaDTO section;
AgendaPage({required this.section});
@override
_AgendaPage createState() => _AgendaPage();
}
class _AgendaPage extends State<AgendaPage> {
AgendaDTO agendaDTO = AgendaDTO();
late Agenda agenda;
late ValueNotifier<List<EventAgenda>> filteredAgenda = ValueNotifier<List<EventAgenda>>([]);
late Uint8List mapIcon;
@override
void initState() {
/*print(widget.section!.data);
agendaDTO = AgendaDTO.fromJson(jsonDecode(widget.section!.data!))!;
print(agendaDTO);*/
agendaDTO = widget.section;
super.initState();
}
@override
void dispose() {
super.dispose();
}
Future<Agenda?> getAndParseJsonInfo(VisitAppContext visitAppContext) async {
try {
if (agendaDTO.id == null) return null;
final dtos = await visitAppContext.clientAPI.sectionAgendaApi!
.sectionAgendaGetUpcomingEvents(agendaDTO.id!);
if (dtos == null) return null;
final events = dtos
.map((dto) => EventAgenda.fromDto(dto, visitAppContext.language))
.toList();
events.sort((a, b) {
if (a.dateFrom == null) return 1;
if (b.dateFrom == null) return -1;
return a.dateFrom!.compareTo(b.dateFrom!);
});
agenda = Agenda(events: events);
filteredAgenda.value = events;
mapIcon = await getByteIcon();
return agenda;
} catch (e) {
return null;
}
}
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;
final VisitAppContext visitAppContext = Provider.of<AppContext>(context).getContext();
return FutureBuilder(future: getAndParseJsonInfo(visitAppContext),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
return Center(
child: Text("Le fichier choisi n'est pas valide")
);
} else {
return Stack(
children: [
Center(
child: Container(
width: size.width,
height: size.height,
color: kBackgroundLight,
child: Padding(
padding: const EdgeInsets.only(left: 8.0, bottom: 2.0, top: 2.0),
child: ValueListenableBuilder<List<EventAgenda>>(
valueListenable: filteredAgenda,
builder: (context, value, _) {
return GridView.builder(
scrollDirection: Axis.vertical, // Changer pour horizontal si nécessaire
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // Nombre de colonnes dans la grid
crossAxisSpacing: 2.0, // Espace entre les colonnes
mainAxisSpacing: 2.0, // Espace entre les lignes
childAspectRatio: 0.65, // Aspect ratio des enfants de la grid
),
itemCount: value.length,
itemBuilder: (BuildContext context, int index) {
EventAgenda eventAgenda = value[index];
return GestureDetector(
onTap: () {
print("${eventAgenda.name}");
(Provider.of<AppContext>(context, listen: false).getContext() as VisitAppContext)
.statisticsService?.track(
VisitEventType.agendaEventTap,
metadata: {'eventId': eventAgenda.name, 'eventTitle': eventAgenda.name},
);
showDialog(
context: context,
builder: (BuildContext context) {
return EventPopup(eventAgenda: eventAgenda, mapProvider: agendaDTO.agendaMapProvider ?? MapProvider.Google, mapIcon: mapIcon);
},
);
},
child: EventListItem(
eventAgenda: eventAgenda,
),
);
},
);
}
),
),
),
),
Align(
alignment: Alignment.centerLeft,
child: MonthFilter(
events: snapshot.data.events,
onMonthSelected: (filteredList) {
print('events sélectionné: $filteredList');
var result = filteredList != null ? filteredList : <EventAgenda>[];
result.sort((a, b) => a.dateFrom!.compareTo(b.dateFrom!));
filteredAgenda.value = result;
}),
),
Positioned(
top: 35,
left: 10,
child: SizedBox(
width: 50,
height: 50,
child: InkWell(
onTap: () {
Navigator.of(context).pop();
},
child: Container(
decoration: const BoxDecoration(
color: kMainColor,
shape: BoxShape.circle,
),
child: const Icon(Icons.arrow_back, size: 23, color: Colors.white)
),
)
),
),
],
);
}
} else if (snapshot.connectionState == ConnectionState.none) {
return Text("No data");
} else {
return Center(
child: Container(
height: size.height * 0.2,
child: LoadingCommon()
)
);
}
},
);
}
} //_webView