Fix agenda + weather finetuning

This commit is contained in:
Thomas Fransolet 2024-02-28 12:01:56 +01:00
parent 0559600efc
commit 9eaad8b0cf
8 changed files with 114 additions and 76 deletions

View File

@ -3,42 +3,52 @@ import 'package:tablet_app/Models/translation.dart';
List<Translation> translations = [
Translation(language: "FR", data: {
"weather.hourly": "Prochaines heures",
"weather.nextdays": "Prochains jours"
"weather.nextdays": "Prochains jours",
"agenda.all": "Tout"
}),
Translation(language: "EN", data: {
"weather.hourly": "Hourly",
"weather.nextdays": "Next days"
"weather.nextdays": "Next days",
"agenda.all": "All"
}),
Translation(language: "DE", data: {
"weather.hourly": "Nächste Stunden",
"weather.nextdays": "Nächsten Tage"
"weather.nextdays": "Nächsten Tage",
"agenda.all": "Alle"
}),
Translation(language: "NL", data: {
"weather.hourly": "Volgende uren",
"weather.nextdays": "Volgende dagen"
"weather.nextdays": "Volgende dagen",
"agenda.all": "Alle"
}),
Translation(language: "IT", data: {
"weather.hourly": "Le prossime ore",
"weather.nextdays": "Prossimi giorni"
"weather.nextdays": "Prossimi giorni",
"agenda.all": "Tutto"
}),
Translation(language: "ES", data: {
"weather.hourly": "Próximas horas",
"weather.nextdays": "Proximos dias"
"weather.nextdays": "Proximos dias",
"agenda.all": "Todo"
}),
Translation(language: "PL", data: {
"weather.hourly": "Następne godziny",
"weather.nextdays": "Następne dni"
"weather.nextdays": "Następne dni",
"agenda.all": "Wszystko"
}),
Translation(language: "CN", data: {
"weather.hourly": "接下来的几个小时",
"weather.nextdays": "未来几天"
"weather.nextdays": "未来几天",
"agenda.all": "全部"
}),
Translation(language: "UK", data: {
"weather.hourly": "Наступні години",
"weather.nextdays": "Наступні дні"
"weather.nextdays": "Наступні дні",
"agenda.all": "все"
}),
Translation(language: "AR", data: {
"weather.hourly": "الساعات القادمة",
"weather.nextdays": "الايام القادمة"
"weather.nextdays": "الايام القادمة",
"agenda.all": "الجميع"
}),
];

View File

@ -8,11 +8,14 @@ import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:manager_api/api.dart';
import 'package:path_provider/path_provider.dart';
import 'package:provider/provider.dart';
import 'package:tablet_app/Components/loading_common.dart';
import 'package:tablet_app/Models/agenda.dart';
import 'package:tablet_app/Models/tabletContext.dart';
import 'package:tablet_app/Screens/Agenda/event_list_item.dart';
import 'package:tablet_app/Screens/Agenda/event_popup.dart';
import 'package:tablet_app/Screens/Agenda/month_filter.dart';
import 'package:tablet_app/app_context.dart';
import 'package:tablet_app/constants.dart';
@ -42,11 +45,16 @@ class _AgendaView extends State<AgendaView> {
super.dispose();
}
Future<Agenda?> getAndParseJsonInfo() async {
Future<Agenda?> getAndParseJsonInfo(TabletAppContext tabletAppContext) async {
try {
// Récupération du contenu JSON depuis l'URL
var httpClient = HttpClient();
var request = await httpClient.getUrl(Uri.parse(agendaDTO.resourceUrl!));
// We need to get detail to get url from resourceId
var resourceIdForSelectedLanguage = agendaDTO.resourceIds!.where((ri) => ri.language == tabletAppContext.language).first.value;
ResourceDTO? resourceDTO = await tabletAppContext.clientAPI!.resourceApi!.resourceGetDetail(resourceIdForSelectedLanguage!);
var request = await httpClient.getUrl(Uri.parse(resourceDTO!.url!));
var response = await request.close();
var jsonString = await response.transform(utf8.decoder).join();
@ -64,8 +72,9 @@ class _AgendaView extends State<AgendaView> {
@override
Widget build(BuildContext context) {
Size size = MediaQuery.of(context).size;
final TabletAppContext tabletAppContext = Provider.of<AppContext>(context).getContext();
return FutureBuilder(future: getAndParseJsonInfo(),
return FutureBuilder(future: getAndParseJsonInfo(tabletAppContext),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.data == null) {
@ -93,7 +102,7 @@ class _AgendaView extends State<AgendaView> {
events: snapshot.data.events,
onMonthSelected: (filteredList) {
print('events sélectionné: $filteredList');
var result = filteredList!;
var result = filteredList != null ? filteredList : <EventAgenda>[];
result.sort((a, b) => a.dateFrom!.compareTo(b.dateFrom!));
filteredAgenda.value = result;
}),

View File

@ -1,5 +1,8 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:tablet_app/Helpers/translationHelper.dart';
import 'package:tablet_app/Models/agenda.dart';
import 'package:tablet_app/app_context.dart';
import 'package:tablet_app/constants.dart';
class MonthFilter extends StatefulWidget {
@ -25,38 +28,47 @@ class _MonthFilterState extends State<MonthFilter> {
@override
Widget build(BuildContext context) {
List<Map<String, dynamic>> sortedMonths = _getSortedMonths();
final appContext = Provider.of<AppContext>(context);
return ListView.builder(
itemCount: sortedMonths.length + 1, // +1 for "Tout (nbr total events)"
itemBuilder: (context, index) {
if (index == 0) {
return _buildAllItem();
return _buildAllItem(appContext);
} else {
final monthYear = sortedMonths[index - 1]['monthYear'];
List<EventAgenda>? filteredEvents = _filterEvents(monthYear);
String monthName = _getTranslatedMonthName(monthYear);
RegExp regExp = RegExp(r'\d{4}');
String annee = regExp.stringMatch(monthYear)!;
var nbrEvents = filteredEvents == null ? 0 : filteredEvents.length;
return ListTile(
title: Text(
'$monthName $annee (${filteredEvents!.length})',
style: TextStyle(
fontSize: 16.0,
fontWeight: _selectedMonth == monthYear ? FontWeight.bold : FontWeight.normal,
color: _selectedMonth == monthYear ? kTestSecondColor : null,
// Vérifier si nbrEvents est supérieur à 0
if (nbrEvents > 0) {
String monthName = _getTranslatedMonthName(monthYear);
RegExp regExp = RegExp(r'\d{4}');
String annee = regExp.stringMatch(monthYear)!;
return ListTile(
title: Text(
'$monthName $annee (${nbrEvents})',
style: TextStyle(
fontSize: 16.0,
fontWeight: _selectedMonth == monthYear ? FontWeight.bold : FontWeight.normal,
color: _selectedMonth == monthYear ? kTestSecondColor : null,
),
),
),
onTap: () {
setState(() {
_selectedMonth = monthYear;
});
widget.onMonthSelected(filteredEvents);
},
tileColor: _selectedMonth == monthYear ? kTestSecondColor : null,
);
onTap: () {
setState(() {
_selectedMonth = monthYear;
});
widget.onMonthSelected(filteredEvents);
},
tileColor: _selectedMonth == monthYear ? kTestSecondColor : null,
);
} else {
// Si nbrEvents est 0, ne retourne pas de widget
return SizedBox.shrink();
}
}
},
);
@ -70,11 +82,11 @@ class _MonthFilterState extends State<MonthFilter> {
return translatedMonthName;
}
Widget _buildAllItem() {
Widget _buildAllItem(AppContext appContext) {
int totalEvents = widget.events.length;
return ListTile(
title: Text(
'Tout ($totalEvents)',
'${TranslationHelper.getFromLocale("agenda.all", appContext.getContext())} ($totalEvents)',
style: TextStyle(
fontSize: 16.0,
fontWeight: _selectedMonth == null ? FontWeight.bold : FontWeight.normal,

View File

@ -49,24 +49,34 @@ class WeatherView extends StatelessWidget {
List<WeatherForecast> nextDay5All = allForecasts.where((af) => (DateTime.fromMillisecondsSinceEpoch(af.dt! * 1000)).day == (today.add(Duration(days: 5))).day).toList();
var nextDay1MiddayTest = nextDay1All.where((nd) => (DateTime.fromMillisecondsSinceEpoch(nd.dt! * 1000)).hour == 12).firstOrNull;
WeatherForecast nextDay1AllSummary = nextDay1MiddayTest != null ? nextDay1MiddayTest : nextDay1All.last;
nextFiveDaysForecast.add(nextDay1AllSummary);
if(nextDay1All.isNotEmpty) {
WeatherForecast nextDay1AllSummary = nextDay1MiddayTest != null ? nextDay1MiddayTest : nextDay1All.last;
nextFiveDaysForecast.add(nextDay1AllSummary);
}
var nextDay2MiddayTest = nextDay2All.where((nd) => (DateTime.fromMillisecondsSinceEpoch(nd.dt! * 1000)).hour == 12).firstOrNull;
WeatherForecast nextDay2Midday = nextDay2MiddayTest != null ? nextDay2MiddayTest : nextDay2All.last;
nextFiveDaysForecast.add(nextDay2Midday);
if(nextDay2All.isNotEmpty) {
WeatherForecast nextDay2Midday = nextDay2MiddayTest != null ? nextDay2MiddayTest : nextDay2All.last;
nextFiveDaysForecast.add(nextDay2Midday);
}
var nextDay3MiddayTest = nextDay3All.where((nd) => (DateTime.fromMillisecondsSinceEpoch(nd.dt! * 1000)).hour == 12).firstOrNull;
WeatherForecast nextDay3Midday = nextDay3MiddayTest != null ? nextDay3MiddayTest : nextDay3All.last;
nextFiveDaysForecast.add(nextDay3Midday);
if(nextDay3All.isNotEmpty) {
WeatherForecast nextDay3Midday = nextDay3MiddayTest != null ? nextDay3MiddayTest : nextDay3All.last;
nextFiveDaysForecast.add(nextDay3Midday);
}
var nextDay4MiddayTest = nextDay4All.where((nd) => (DateTime.fromMillisecondsSinceEpoch(nd.dt! * 1000)).hour == 12).firstOrNull;
WeatherForecast nextDay4Midday = nextDay4MiddayTest != null ? nextDay4MiddayTest : nextDay4All.last;
nextFiveDaysForecast.add(nextDay4Midday);
if(nextDay4All.isNotEmpty) {
WeatherForecast nextDay4Midday = nextDay4MiddayTest != null ? nextDay4MiddayTest : nextDay4All.last;
nextFiveDaysForecast.add(nextDay4Midday);
}
var nextDay5MiddayTest = nextDay5All.where((nd) => (DateTime.fromMillisecondsSinceEpoch(nd.dt! * 1000)).hour == 12).firstOrNull;
WeatherForecast nextDay5Midday = nextDay5MiddayTest != null ? nextDay5MiddayTest : nextDay5All.last;
nextFiveDaysForecast.add(nextDay5Midday);
if(nextDay5All.isNotEmpty) {
WeatherForecast nextDay5Midday = nextDay5MiddayTest != null ? nextDay5MiddayTest : nextDay5All.last;
nextFiveDaysForecast.add(nextDay5Midday);
}
return nextFiveDaysForecast;
}
@ -272,8 +282,8 @@ class WeatherView extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: List.generate(
nbrNextHours,
(index) {
getNextFiveDaysForecast(weatherData.list!).length, // nbrNextHours
(index) {
final weatherForecastNextDay = getNextFiveDaysForecast(weatherData.list!)[index];
return Padding(
padding: const EdgeInsets.all(8.0),

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:manager_api/api.dart';
import 'package:provider/provider.dart';
import 'package:tablet_app/Models/tabletContext.dart';
@ -50,7 +51,6 @@ class _DownloadConfigurationWidgetState extends State<DownloadConfigurationWidge
Permission.storage,
].request();
if(statuses[Permission.storage] == PermissionStatus.granted) {
try{
try {
Directory directory = Directory('${tabletAppContext.localPath}');
@ -110,6 +110,16 @@ class _DownloadConfigurationWidgetState extends State<DownloadConfigurationWidge
return false;
}
} else {
print("PermissionStatus.granted NOT GRANTED");
Fluttertoast.showToast(
msg: "PermissionStatus not granted",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.BOTTOM,
timeInSecForIosWeb: 1,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 16.0
);
return false;
}
}

View File

@ -2424,12 +2424,11 @@ components:
type: object
additionalProperties: false
properties:
resourceId:
type: string
nullable: true
resourceUrl:
type: string
resourceIds:
type: array
nullable: true
items:
$ref: '#/components/schemas/TranslationDTO'
User:
type: object
additionalProperties: false

View File

@ -8,8 +8,7 @@ import 'package:manager_api/api.dart';
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**resourceId** | **String** | | [optional]
**resourceUrl** | **String** | | [optional]
**resourceIds** | [**List<TranslationDTO>**](TranslationDTO.md) | | [optional] [default to const []]
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

View File

@ -13,39 +13,29 @@ part of openapi.api;
class AgendaDTO {
/// Returns a new [AgendaDTO] instance.
AgendaDTO({
this.resourceId,
this.resourceUrl,
this.resourceIds = const [],
});
String? resourceId;
String? resourceUrl;
List<TranslationDTO>? resourceIds;
@override
bool operator ==(Object other) => identical(this, other) || other is AgendaDTO &&
other.resourceId == resourceId &&
other.resourceUrl == resourceUrl;
other.resourceIds == resourceIds;
@override
int get hashCode =>
// ignore: unnecessary_parenthesis
(resourceId == null ? 0 : resourceId!.hashCode) +
(resourceUrl == null ? 0 : resourceUrl!.hashCode);
(resourceIds == null ? 0 : resourceIds!.hashCode);
@override
String toString() => 'AgendaDTO[resourceId=$resourceId, resourceUrl=$resourceUrl]';
String toString() => 'AgendaDTO[resourceIds=$resourceIds]';
Map<String, dynamic> toJson() {
final json = <String, dynamic>{};
if (this.resourceId != null) {
json[r'resourceId'] = this.resourceId;
if (this.resourceIds != null) {
json[r'resourceIds'] = this.resourceIds;
} else {
json[r'resourceId'] = null;
}
if (this.resourceUrl != null) {
json[r'resourceUrl'] = this.resourceUrl;
} else {
json[r'resourceUrl'] = null;
json[r'resourceIds'] = null;
}
return json;
}
@ -69,8 +59,7 @@ class AgendaDTO {
}());
return AgendaDTO(
resourceId: mapValueOfType<String>(json, r'resourceId'),
resourceUrl: mapValueOfType<String>(json, r'resourceUrl'),
resourceIds: TranslationDTO.listFromJson(json[r'resourceIds']),
);
}
return null;