From 61cb8f2c698a1fa55b8e4c30880b9cc90bb06962 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Mon, 23 Dec 2024 22:36:16 +0100 Subject: [PATCH 01/20] feat/create foundation for many tiles in digital guide and fetch adapted toilets with initial presentation --- lib/config/nav_bar_config.dart | 1 + .../data/models/digital_guide_response.dart | 42 ++++++++ .../digital_guide_response_extended.dart | 27 +++++ .../repository/digital_guide_repository.dart | 43 ++++++++ .../digital_guide_features_section.dart | 9 +- .../widgets/digital_guide_nav_link.dart | 2 +- .../data/models/adapted_toilet.dart | 45 +++++++++ .../adapted_toilets_repository.dart | 42 ++++++++ .../adapted_toilet_detail_view.dart | 57 +++++++++++ ...dapted_toilets_expansion_tile_content.dart | 99 +++++++++++++++++++ .../widgets/science_clubs_section.dart | 6 ++ lib/features/navigator/app_router.dart | 5 + .../navigator/utils/navigation_commands.dart | 5 + lib/l10n/app_pl.arb | 6 +- 14 files changed, 384 insertions(+), 5 deletions(-) create mode 100644 lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart create mode 100644 lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart create mode 100644 lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart create mode 100644 lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart diff --git a/lib/config/nav_bar_config.dart b/lib/config/nav_bar_config.dart index bfa09b84..f77bc957 100644 --- a/lib/config/nav_bar_config.dart +++ b/lib/config/nav_bar_config.dart @@ -62,6 +62,7 @@ extension IsRouteATabViewX on PageRouteInfo { DepartmentDetailRoute.name => context.localize.department, ScienceClubDetailRoute.name => context.localize.scientific_cirlces, GuideDetailRoute.name => context.localize.guide, + DigitalGuideRoute.name => context.localize.digital_guide, _ => null, }; } diff --git a/lib/features/digital_guide_view/data/models/digital_guide_response.dart b/lib/features/digital_guide_view/data/models/digital_guide_response.dart index 7d43ec0c..2357fd96 100644 --- a/lib/features/digital_guide_view/data/models/digital_guide_response.dart +++ b/lib/features/digital_guide_view/data/models/digital_guide_response.dart @@ -57,6 +57,7 @@ class DigitalGuideResponse with _$DigitalGuideResponse { required List images, @JsonKey(name: "evacuation_map") required int evacuationMapId, String? imageUrl, + @JsonKey(name: "levels") required List levelsIndices, }) = _DigitalGuideResponse; factory DigitalGuideResponse.fromJson(Map json) => @@ -87,6 +88,47 @@ class DigitalGuideTranslation with _$DigitalGuideTranslation { _$DigitalGuideTranslationFromJson(json); } +@freezed +class LevelNotFull with _$LevelNotFull { + const factory LevelNotFull({ + required int id, + required LevelTranslations translations, + @JsonKey(name: "regions") required List regionIndices, + }) = _LevelNotFull; + + factory LevelNotFull.fromJson(Map json) => + _$LevelNotFullFromJson(json); +} + +@freezed +class LevelTranslations with _$LevelTranslations { + const factory LevelTranslations({ + @JsonKey(name: "pl") required LevelTranslation plTranslation, + }) = _LevelTranslations; + + factory LevelTranslations.fromJson(Map json) => + _$LevelTranslationsFromJson(json); +} + +@freezed +class LevelTranslation with _$LevelTranslation { + const factory LevelTranslation({ + required String name, + }) = _LevelTranslation; + + factory LevelTranslation.fromJson(Map json) => + _$LevelTranslationFromJson(json); +} + +@freezed +class Region with _$Region { + const factory Region({ + @JsonKey(name: "adapted_toilets") required List adaptedToiletsIndices, + }) = _Region; + + factory Region.fromJson(Map json) => _$RegionFromJson(json); +} + bool _stringToBool(String value) { return value == "True"; } diff --git a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart index ea3d82f3..42f04694 100644 --- a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart +++ b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart @@ -23,6 +23,7 @@ class DigitalGuideResponseExtended { required this.surroundingId, required this.images, required this.imageUrl, + required this.levels, required this.entraces, required this.evacuation, }); @@ -42,12 +43,14 @@ class DigitalGuideResponseExtended { final int surroundingId; final List images; final String? imageUrl; + final List levels; final DigitalGuideEvacuation evacuation; final IList entraces; factory DigitalGuideResponseExtended.fromDigitalGuideResponse({ required DigitalGuideResponse digitalGuideResponse, required String? imageUrl, + required List levels, required DigitalGuideEvacuation evacuation, required IList entraces, }) { @@ -67,8 +70,32 @@ class DigitalGuideResponseExtended { surroundingId: digitalGuideResponse.surroundingId, images: digitalGuideResponse.images, imageUrl: imageUrl, + levels: levels, entraces: entraces, evacuation: evacuation, ); } } + +class Level { + const Level({ + required this.id, + required this.translations, + required this.regions, + }); + + final int id; + final LevelTranslations translations; + final List regions; + + factory Level.create({ + required LevelNotFull levelNotFull, + required List regions, + }) { + return Level( + id: levelNotFull.id, + translations: levelNotFull.translations, + regions: regions, + ); + } +} diff --git a/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart b/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart index 270606cb..0a71e568 100644 --- a/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart +++ b/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart @@ -24,9 +24,13 @@ Future getDigitalGuideDataExtended( await ref.watch(getDigitalGuideEvacuationProvider(id).future); final entraces = await ref .watch(getDigitalGuideEntracesProvider(digitalGuideResponse.id).future); + final levels = await ref + .watch(GetLevelsProvider(digitalGuideResponse.levelsIndices).future); + debugPrint("Levels count: ${levels.length}"); return DigitalGuideResponseExtended.fromDigitalGuideResponse( digitalGuideResponse: digitalGuideResponse, imageUrl: imageUrl, + levels: levels, evacuation: evacuation, entraces: entraces, ); @@ -54,6 +58,45 @@ Future getImageUrl(Ref ref, int id) async { return imageUrl; } +@riverpod +Future> getLevels(Ref ref, List levelsIndices) async { + final dio = ref.read(restClientProvider); + dio.options.headers["Authorization"] = + "Token ${Env.digitalGuideAuthorizationToken}"; + + final levelsFutures = levelsIndices.map((levelID) async { + final levelResponse = + await dio.get("${Env.digitalGuideUrl}/levels/$levelID"); + final levelNotFull = + LevelNotFull.fromJson(levelResponse.data as Map); + final regionsFutures = levelNotFull.regionIndices.map((regionID) async { + final regionResponse = + await dio.get("${Env.digitalGuideUrl}/regions/$regionID"); + return Region.fromJson(regionResponse.data as Map); + }).toList(); + final regions = await Future.wait(regionsFutures); + return Level.create(levelNotFull: levelNotFull, regions: regions); + }).toList(); + + final levelsList = await Future.wait(levelsFutures); + + return levelsList; +} + +@riverpod +Future> getRegions(Ref ref, List regionsIndices) async { + final dio = ref.read(restClientProvider); + dio.options.headers["Authorization"] = + "Token ${Env.digitalGuideAuthorizationToken}"; + + final regionsIterable = regionsIndices.map((id) async { + final response = await dio.get("${Env.digitalGuideUrl}/regions/$id"); + return Region.fromJson(response.data as Map); + }); + + return Future.wait(regionsIterable); +} + @riverpod Future getDigitalGuideBuildingData( Ref ref, diff --git a/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart b/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart index 6fa5817f..9332c409 100644 --- a/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart +++ b/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart @@ -4,6 +4,7 @@ import "package:flutter/widgets.dart"; import "../../../../utils/context_extensions.dart"; import "../../../../widgets/my_expansion_tile.dart"; import "../../data/models/digital_guide_response_extended.dart"; +import "../../tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart"; import "../../tabs/amenities/presentation/amenities_expansion_tile_content.dart"; import "../../tabs/evacuation/evacuation_widget.dart"; import "../../tabs/localization/presentation/localization_expansion_tile_content.dart"; @@ -54,8 +55,12 @@ class DigitalGuideFeaturesSection extends StatelessWidget { content: [LocalizationExpansionTileContent()], ), ( - title: context.localize.toilets, - content: [LocalizationExpansionTileContent()], + title: context.localize.adapted_toilets, + content: [ + AdaptedToiletsExpansionTileContent( + digitalGuideResponseExtended: digitalGuideResponseExtended, + ), + ], ), ( title: context.localize.micro_navigation, diff --git a/lib/features/digital_guide_view/presentation/widgets/digital_guide_nav_link.dart b/lib/features/digital_guide_view/presentation/widgets/digital_guide_nav_link.dart index 2b27b2c4..13d96a8f 100644 --- a/lib/features/digital_guide_view/presentation/widgets/digital_guide_nav_link.dart +++ b/lib/features/digital_guide_view/presentation/widgets/digital_guide_nav_link.dart @@ -31,7 +31,7 @@ class DigitalGuideNavLink extends StatelessWidget { children: [ Text( text, - style: context.textTheme.title, + style: context.textTheme.body, overflow: TextOverflow.ellipsis, ), Icon( diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart new file mode 100644 index 00000000..f9fdd5b3 --- /dev/null +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart @@ -0,0 +1,45 @@ +// ignore_for_file: invalid_annotation_target + +import "package:freezed_annotation/freezed_annotation.dart"; + +part "adapted_toilet.freezed.dart"; +part "adapted_toilet.g.dart"; + +@freezed +class AdaptedToilet with _$AdaptedToilet { + const factory AdaptedToilet({ + required AdaptedToiletTranslations translations, + @JsonKey(name: "is_access_accessible_for_pwd", fromJson: _stringToBool) + required bool isAccessAccessibleForPwd, + }) = _AdaptedToilet; + + factory AdaptedToilet.fromJson(Map json) => + _$AdaptedToiletFromJson(json); +} + +@freezed +class AdaptedToiletTranslations with _$AdaptedToiletTranslations { + const factory AdaptedToiletTranslations({ + @JsonKey(name: "pl") required AdaptedToiletTranslation plTranslation, + }) = _AdaptedToiletTranslations; + + factory AdaptedToiletTranslations.fromJson(Map json) => + _$AdaptedToiletTranslationsFromJson(json); +} + +@freezed +class AdaptedToiletTranslation with _$AdaptedToiletTranslation { + const factory AdaptedToiletTranslation({ + required String location, + @JsonKey(name: "number_of_cabins") required String numberOfCabins, + @JsonKey(name: "is_access_accessible_for_pwd_comment") + required String isAccessAccessibleForPwdComment, + }) = _AdaptedToiletTranslation; + + factory AdaptedToiletTranslation.fromJson(Map json) => + _$AdaptedToiletTranslationFromJson(json); +} + +bool _stringToBool(String str) { + return str == "True"; +} diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart new file mode 100644 index 00000000..b2564a19 --- /dev/null +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart @@ -0,0 +1,42 @@ +import "package:flutter/foundation.dart"; +import "package:flutter/material.dart"; +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:riverpod_annotation/riverpod_annotation.dart"; + +import "../../../../../../api_base_rest/client/dio_client.dart"; +import "../../../../../../config/env.dart"; +import "../../../../data/models/digital_guide_response_extended.dart"; +import "../models/adapted_toilet.dart"; + +part "adapted_toilets_repository.g.dart"; + +@riverpod +Future>> getAdaptedToiltes( + Ref ref, + List levels, +) async { + final dio = ref.read(restClientProvider); + dio.options.headers["Authorization"] = + "Token ${Env.digitalGuideAuthorizationToken}"; + + final Map> adaptedToiletsMap = {}; + + for (final level in levels) { + final adaptedToiletsIDs = level.regions + .fold([], (list, region) => list + region.adaptedToiletsIndices); + + final adaptedToiletsIterable = adaptedToiletsIDs.map((id) async { + final adaptedToiletUrl = "${Env.digitalGuideUrl}/adapted_toilets/$id"; + final response = await dio.get(adaptedToiletUrl); + return AdaptedToilet.fromJson(response.data as Map); + }); + + final adaptedToiletsList = await Future.wait(adaptedToiletsIterable); + + adaptedToiletsMap[level.id] = adaptedToiletsList; + } + + debugPrint("map lenght: ${adaptedToiletsMap.length}"); + + return adaptedToiletsMap; +} diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart new file mode 100644 index 00000000..ff9cf8ea --- /dev/null +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart @@ -0,0 +1,57 @@ +import "package:auto_route/auto_route.dart"; +import "package:flutter/material.dart"; +import "package:flutter_riverpod/flutter_riverpod.dart"; + +import "../../../../../config/ui_config.dart"; +import "../../../../../theme/app_theme.dart"; +import "../../../../../utils/context_extensions.dart"; +import "../../../../../widgets/detail_views/detail_view_app_bar.dart"; +import "../data/models/adapted_toilet.dart"; + +@RoutePage() +class AdaptedToiletDetailView extends ConsumerWidget { + const AdaptedToiletDetailView({ + required this.adaptedToilet, + }); + + final AdaptedToilet adaptedToilet; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Scaffold( + appBar: DetailViewAppBar( + actions: const [], + ), + body: Padding( + padding: const EdgeInsets.symmetric( + horizontal: DigitalGuideConfig.heightMedium, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + context.localize.adapted_toilet_description, + style: context.textTheme.title.copyWith(fontSize: 18), + ), + const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + Text( + "• ${adaptedToilet.translations.plTranslation.location}", + style: context.textTheme.body.copyWith(fontSize: 16), + ), + Text( + "• ${adaptedToilet.translations.plTranslation.numberOfCabins}", + style: context.textTheme.body.copyWith(fontSize: 16), + ), + if (!adaptedToilet.isAccessAccessibleForPwd) + Text( + "• ${adaptedToilet.translations.plTranslation.isAccessAccessibleForPwdComment}", + style: context.textTheme.body.copyWith(fontSize: 16), + ), + ], + ), + ), + ); + } +} diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart new file mode 100644 index 00000000..6dfd5544 --- /dev/null +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -0,0 +1,99 @@ +import "package:flutter/material.dart"; +import "package:flutter_riverpod/flutter_riverpod.dart"; + +import "../../../../../config/ui_config.dart"; +import "../../../../../theme/app_theme.dart"; +import "../../../../../utils/context_extensions.dart"; +import "../../../../../widgets/my_error_widget.dart"; +import "../../../../navigator/utils/navigation_commands.dart"; +import "../../../data/models/digital_guide_response_extended.dart"; +import "../../../presentation/widgets/digital_guide_nav_link.dart"; +import "../data/models/adapted_toilet.dart"; +import "../data/repository/adapted_toilets_repository.dart"; + +class AdaptedToiletsExpansionTileContent extends ConsumerWidget { + const AdaptedToiletsExpansionTileContent({ + required this.digitalGuideResponseExtended, + }); + + final DigitalGuideResponseExtended digitalGuideResponseExtended; + + @override + Widget build(BuildContext context, WidgetRef ref) { + debugPrint("AdaptedToiletsExpansionTileContent"); + final asyncAdaptedToilets = ref + .watch(GetAdaptedToiltesProvider(digitalGuideResponseExtended.levels)); + debugPrint("After fetching data"); + debugPrint("asyncAdaptedToilets: ${asyncAdaptedToilets.value}"); + return asyncAdaptedToilets.when( + data: (adaptedToiletsData) => _AdaptedToiletsExpansionTileContent( + levels: digitalGuideResponseExtended.levels + .where( + (level) => + adaptedToiletsData.containsKey(level.id) && + adaptedToiletsData[level.id]!.isNotEmpty, + ) + .toList(), + adaptedToiletsData: adaptedToiletsData, + ), + error: (error, stackTrace) => MyErrorWidget(error), + loading: () => const Center( + child: CircularProgressIndicator(), + ), + ); + } +} + +class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { + const _AdaptedToiletsExpansionTileContent({ + required this.levels, + required this.adaptedToiletsData, + }); + + final List levels; + final Map> adaptedToiletsData; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return Padding( + padding: const EdgeInsets.only( + top: DigitalGuideConfig.heightMedium, + left: DigitalGuideConfig.heightMedium, + right: DigitalGuideConfig.heightMedium, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: levels.map((level) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + level.translations.plTranslation.name, + style: context.textTheme.title, + ), + const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + ListView.separated( + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) => DigitalGuideNavLink( + onTap: () async { + await ref.navigateAdaptedToiletDetails( + adaptedToiletsData[level.id]![index], + ); + }, + text: context.localize.adapted_toilet_description, + ), + separatorBuilder: (context, index) => const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + itemCount: adaptedToiletsData[level.id]!.length, + shrinkWrap: true, + ), + ], + ); + }).toList(), + ), + ); + } +} diff --git a/lib/features/home_view/widgets/science_clubs_section.dart b/lib/features/home_view/widgets/science_clubs_section.dart index b02c3a4e..edababc7 100644 --- a/lib/features/home_view/widgets/science_clubs_section.dart +++ b/lib/features/home_view/widgets/science_clubs_section.dart @@ -18,6 +18,12 @@ class ScienceClubsSection extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) => Column( children: [ + FilledButton( + onPressed: () async { + await ref.navigateDigitalGuide(313); + }, + child: const Text("navigate to digital guide mock"), + ), SubsectionHeader( title: context.localize.study_circles, actionTitle: context.localize.list, diff --git a/lib/features/navigator/app_router.dart b/lib/features/navigator/app_router.dart index 8c6cb1f6..25aa4eab 100644 --- a/lib/features/navigator/app_router.dart +++ b/lib/features/navigator/app_router.dart @@ -8,6 +8,8 @@ import "../buildings_view/buildings_view.dart"; import "../department_detail_view/department_detail_view.dart"; import "../departments_view/departments_view.dart"; import "../digital_guide_view/presentation/digital_guide_view.dart"; +import "../digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart"; +import "../digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart"; import "../guide_detail_view/guide_detail_view.dart"; import "../guide_view/guide_view.dart"; import "../home_view/home_view.dart"; @@ -99,6 +101,9 @@ class AppRouter extends RootStackRouter { path: "/digital-guide/:id", page: DigitalGuideRoute.page, ), + AutoRoute( + page: AdaptedToiletDetailRoute.page, + ), AutoRoute( path: "/aboutUs", page: AboutUsRoute.page, diff --git a/lib/features/navigator/utils/navigation_commands.dart b/lib/features/navigator/utils/navigation_commands.dart index 5c492ab6..89cb0cf1 100644 --- a/lib/features/navigator/utils/navigation_commands.dart +++ b/lib/features/navigator/utils/navigation_commands.dart @@ -3,6 +3,7 @@ import "dart:async"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "../../buildings_view/model/building_model.dart"; +import "../../digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart"; import "../../parkings_view/models/parking.dart"; import "../app_router.dart"; import "../navigation_controller.dart"; @@ -80,4 +81,8 @@ extension NavigationX on WidgetRef { Future navigateDigitalGuide(int id) async { await _router.push(DigitalGuideRoute(id: id)); } + + Future navigateAdaptedToiletDetails(AdaptedToilet adaptedToilet) async { + await _router.push(AdaptedToiletDetailRoute(adaptedToilet: adaptedToilet)); + } } diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index 7e46e87b..d1fa555c 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -162,7 +162,8 @@ "transport" : "Dojazd", "entrances" : "Wejścia", "elevators" : "Windy", - "toilets" : "Toilets", + "adapted_toilets" : "Toalety dostosowane", + "adapted_toilet_description": "Toaleta dla osób z niepełnosprawnościami", "micro_navigation" : "Mikronawigacja", "building_structure" : "Struktura budynku", "room_information" : "Pomieszczenia", @@ -209,5 +210,6 @@ "forecasted_number_of_users": "Średnia liczba użytkowników z 21 dni", "sks_chart_title" : "Przybliżona liczba osób w Strefie Kultury Studenckiej", "number_of_people" : "Liczba osób", - "evacuation_text": "Ewakuacja i pierwsza pomoc" + "evacuation_text": "Ewakuacja i pierwsza pomoc", + "digital_guide": "Przeowdnik" } From 309ca90faf16748b86bb11654ed06df085cbdf4d Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Fri, 27 Dec 2024 13:09:43 +0100 Subject: [PATCH 02/20] feat: adapted toilet detail view --- .../data/models/digital_guide_response.dart | 1 + .../digital_guide_response_extended.dart | 3 + .../repository/digital_guide_repository.dart | 4 +- .../digital_guide_features_section.dart | 27 +++- .../widgets/digital_guide_nav_link.dart | 11 +- .../data/models/adapted_toilet.dart | 83 +++++------ .../data/models/adapted_toilet_not_full.dart | 66 ++++++++ .../adapted_toilets_repository.dart | 29 +++- .../adapted_toilet_detail_view.dart | 141 +++++++++++++++--- ...dapted_toilets_expansion_tile_content.dart | 23 ++- lib/l10n/app_pl.arb | 37 ++++- lib/widgets/my_point_widget.dart | 39 +++++ 12 files changed, 370 insertions(+), 94 deletions(-) create mode 100644 lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart create mode 100644 lib/widgets/my_point_widget.dart diff --git a/lib/features/digital_guide_view/data/models/digital_guide_response.dart b/lib/features/digital_guide_view/data/models/digital_guide_response.dart index 2357fd96..fb0d3611 100644 --- a/lib/features/digital_guide_view/data/models/digital_guide_response.dart +++ b/lib/features/digital_guide_view/data/models/digital_guide_response.dart @@ -92,6 +92,7 @@ class DigitalGuideTranslation with _$DigitalGuideTranslation { class LevelNotFull with _$LevelNotFull { const factory LevelNotFull({ required int id, + @JsonKey(name: "floor_number") required int floorNumber, required LevelTranslations translations, @JsonKey(name: "regions") required List regionIndices, }) = _LevelNotFull; diff --git a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart index 42f04694..6e723228 100644 --- a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart +++ b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart @@ -80,11 +80,13 @@ class DigitalGuideResponseExtended { class Level { const Level({ required this.id, + required this.floorNumber, required this.translations, required this.regions, }); final int id; + final int floorNumber; final LevelTranslations translations; final List regions; @@ -94,6 +96,7 @@ class Level { }) { return Level( id: levelNotFull.id, + floorNumber: levelNotFull.floorNumber, translations: levelNotFull.translations, regions: regions, ); diff --git a/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart b/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart index 0a71e568..9561c5f2 100644 --- a/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart +++ b/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart @@ -26,7 +26,6 @@ Future getDigitalGuideDataExtended( .watch(getDigitalGuideEntracesProvider(digitalGuideResponse.id).future); final levels = await ref .watch(GetLevelsProvider(digitalGuideResponse.levelsIndices).future); - debugPrint("Levels count: ${levels.length}"); return DigitalGuideResponseExtended.fromDigitalGuideResponse( digitalGuideResponse: digitalGuideResponse, imageUrl: imageUrl, @@ -79,6 +78,9 @@ Future> getLevels(Ref ref, List levelsIndices) async { }).toList(); final levelsList = await Future.wait(levelsFutures); + levelsList.sort( + (level1, level2) => level1.floorNumber.compareTo(level2.floorNumber), + ); return levelsList; } diff --git a/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart b/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart index 9332c409..06085bc7 100644 --- a/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart +++ b/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart @@ -54,14 +54,25 @@ class DigitalGuideFeaturesSection extends StatelessWidget { title: context.localize.elevators, content: [LocalizationExpansionTileContent()], ), - ( - title: context.localize.adapted_toilets, - content: [ - AdaptedToiletsExpansionTileContent( - digitalGuideResponseExtended: digitalGuideResponseExtended, - ), - ], - ), + if (digitalGuideResponseExtended.levels.fold( + 0, + (levelValue, levelElement) => + levelValue + + levelElement.regions.fold( + 0, + (regionValue, regionElement) => + regionValue + regionElement.adaptedToiletsIndices.length, + ), + ) > + 0) + ( + title: context.localize.adapted_toilets, + content: [ + AdaptedToiletsExpansionTileContent( + digitalGuideResponseExtended: digitalGuideResponseExtended, + ), + ], + ), ( title: context.localize.micro_navigation, content: [LocalizationExpansionTileContent()], diff --git a/lib/features/digital_guide_view/presentation/widgets/digital_guide_nav_link.dart b/lib/features/digital_guide_view/presentation/widgets/digital_guide_nav_link.dart index 13d96a8f..175231f5 100644 --- a/lib/features/digital_guide_view/presentation/widgets/digital_guide_nav_link.dart +++ b/lib/features/digital_guide_view/presentation/widgets/digital_guide_nav_link.dart @@ -29,10 +29,13 @@ class DigitalGuideNavLink extends StatelessWidget { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - text, - style: context.textTheme.body, - overflow: TextOverflow.ellipsis, + Expanded( + child: Text( + text, + style: context.textTheme.body, + overflow: TextOverflow.ellipsis, + maxLines: 3, + ), ), Icon( Icons.arrow_forward_ios, diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart index f9fdd5b3..1cc3151e 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart @@ -1,45 +1,40 @@ -// ignore_for_file: invalid_annotation_target - -import "package:freezed_annotation/freezed_annotation.dart"; - -part "adapted_toilet.freezed.dart"; -part "adapted_toilet.g.dart"; - -@freezed -class AdaptedToilet with _$AdaptedToilet { - const factory AdaptedToilet({ - required AdaptedToiletTranslations translations, - @JsonKey(name: "is_access_accessible_for_pwd", fromJson: _stringToBool) - required bool isAccessAccessibleForPwd, - }) = _AdaptedToilet; - - factory AdaptedToilet.fromJson(Map json) => - _$AdaptedToiletFromJson(json); -} - -@freezed -class AdaptedToiletTranslations with _$AdaptedToiletTranslations { - const factory AdaptedToiletTranslations({ - @JsonKey(name: "pl") required AdaptedToiletTranslation plTranslation, - }) = _AdaptedToiletTranslations; - - factory AdaptedToiletTranslations.fromJson(Map json) => - _$AdaptedToiletTranslationsFromJson(json); -} - -@freezed -class AdaptedToiletTranslation with _$AdaptedToiletTranslation { - const factory AdaptedToiletTranslation({ - required String location, - @JsonKey(name: "number_of_cabins") required String numberOfCabins, - @JsonKey(name: "is_access_accessible_for_pwd_comment") - required String isAccessAccessibleForPwdComment, - }) = _AdaptedToiletTranslation; - - factory AdaptedToiletTranslation.fromJson(Map json) => - _$AdaptedToiletTranslationFromJson(json); -} - -bool _stringToBool(String str) { - return str == "True"; +import "adapted_toilet_not_full.dart"; + +class AdaptedToilet { + const AdaptedToilet({ + required this.translations, + required this.isAccessAccessibleForPwd, + required this.hasAdditionalPurpose, + required this.isNeedAuthorization, + required this.isEntranceGraphicallyMarked, + required this.isMarked, + required this.imagesURLs, + required this.doorsIndices, + }); + + final AdaptedToiletTranslations translations; + final bool isAccessAccessibleForPwd; + final int hasAdditionalPurpose; + final String isNeedAuthorization; + final bool isEntranceGraphicallyMarked; + final bool isMarked; + final List imagesURLs; + final List doorsIndices; + + factory AdaptedToilet.create({ + required AdaptedToiletNotFull adaptedToiletNotFull, + required List imagesURLs, + }) { + return AdaptedToilet( + translations: adaptedToiletNotFull.translations, + isAccessAccessibleForPwd: adaptedToiletNotFull.isAccessAccessibleForPwd, + hasAdditionalPurpose: adaptedToiletNotFull.hasAdditionalPurpose, + isNeedAuthorization: adaptedToiletNotFull.isNeedAuthorization, + isEntranceGraphicallyMarked: + adaptedToiletNotFull.isEntranceGraphicallyMarked, + isMarked: adaptedToiletNotFull.isMarked, + imagesURLs: imagesURLs, + doorsIndices: adaptedToiletNotFull.doorsIndices, + ); + } } diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart new file mode 100644 index 00000000..e699b4bb --- /dev/null +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart @@ -0,0 +1,66 @@ +// ignore_for_file: invalid_annotation_target + +import "package:freezed_annotation/freezed_annotation.dart"; + +part "adapted_toilet_not_full.freezed.dart"; +part "adapted_toilet_not_full.g.dart"; + +@freezed +class AdaptedToiletNotFull with _$AdaptedToiletNotFull { + const factory AdaptedToiletNotFull({ + required AdaptedToiletTranslations translations, + @JsonKey(name: "is_access_accessible_for_pwd", fromJson: _stringToBool) + required bool isAccessAccessibleForPwd, + @JsonKey(name: "has_additional_purpose", fromJson: _stringToInt) + required int hasAdditionalPurpose, + @JsonKey(name: "is_need_authorization") required String isNeedAuthorization, + @JsonKey(name: "is_entrance_graphically_marked", fromJson: _stringToBool) + required bool isEntranceGraphicallyMarked, + @JsonKey(name: "is_marked", fromJson: _stringToBool) required bool isMarked, + @JsonKey(name: "images") required List imagesIndices, + @JsonKey(name: "doors") required List doorsIndices, + }) = _AdaptedToiletNotFull; + + factory AdaptedToiletNotFull.fromJson(Map json) => + _$AdaptedToiletNotFullFromJson(json); +} + +@freezed +class AdaptedToiletTranslations with _$AdaptedToiletTranslations { + const factory AdaptedToiletTranslations({ + @JsonKey(name: "pl") required AdaptedToiletTranslation plTranslation, + }) = _AdaptedToiletTranslations; + + factory AdaptedToiletTranslations.fromJson(Map json) => + _$AdaptedToiletTranslationsFromJson(json); +} + +@freezed +class AdaptedToiletTranslation with _$AdaptedToiletTranslation { + const factory AdaptedToiletTranslation({ + required String location, + @JsonKey(name: "toilet_description") required String toiletDescription, + @JsonKey(name: "number_of_cabins") required String numberOfCabins, + @JsonKey(name: "is_access_accessible_for_pwd_comment") + required String isAccessAccessibleForPwdComment, + @JsonKey(name: "is_need_authorization_comment") + required String isNeedAuthorizationComment, + @JsonKey(name: "is_area_allowing_movement_in_front_entrance_comment") + required String isAreaAllowingMovementInFrontEntranceComment, + @JsonKey(name: "is_entrance_graphically_marked_comment") + required String isEntranceGraphicallyMarkedComment, + @JsonKey(name: "is_marked_comment") required String isMarkedComment, + required String comment, + }) = _AdaptedToiletTranslation; + + factory AdaptedToiletTranslation.fromJson(Map json) => + _$AdaptedToiletTranslationFromJson(json); +} + +bool _stringToBool(String str) { + return str == "True"; +} + +int _stringToInt(String str) { + return int.tryParse(str) ?? 1; +} diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart index b2564a19..8d9539cc 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart @@ -1,12 +1,12 @@ -import "package:flutter/foundation.dart"; -import "package:flutter/material.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; import "../../../../../../api_base_rest/client/dio_client.dart"; import "../../../../../../config/env.dart"; import "../../../../data/models/digital_guide_response_extended.dart"; +import "../../../../data/repository/digital_guide_repository.dart"; import "../models/adapted_toilet.dart"; +import "../models/adapted_toilet_not_full.dart"; part "adapted_toilets_repository.g.dart"; @@ -25,10 +25,25 @@ Future>> getAdaptedToiltes( final adaptedToiletsIDs = level.regions .fold([], (list, region) => list + region.adaptedToiletsIndices); - final adaptedToiletsIterable = adaptedToiletsIDs.map((id) async { - final adaptedToiletUrl = "${Env.digitalGuideUrl}/adapted_toilets/$id"; - final response = await dio.get(adaptedToiletUrl); - return AdaptedToilet.fromJson(response.data as Map); + final adaptedToiletsIterable = + adaptedToiletsIDs.map((adaptedTouiletID) async { + final adaptedToiletNotFullURL = + "${Env.digitalGuideUrl}/adapted_toilets/$adaptedTouiletID"; + final adaptedToiletNotFullResponse = + await dio.get(adaptedToiletNotFullURL); + final adaptedToiletNotFull = AdaptedToiletNotFull.fromJson( + adaptedToiletNotFullResponse.data as Map, + ); + final imagesURLsFutures = + adaptedToiletNotFull.imagesIndices.map((imageID) async { + final imageURL = await ref.watch(GetImageUrlProvider(imageID).future); + return imageURL!; + }); + final imagesURLs = await Future.wait(imagesURLsFutures); + return AdaptedToilet.create( + adaptedToiletNotFull: adaptedToiletNotFull, + imagesURLs: imagesURLs, + ); }); final adaptedToiletsList = await Future.wait(adaptedToiletsIterable); @@ -36,7 +51,5 @@ Future>> getAdaptedToiltes( adaptedToiletsMap[level.id] = adaptedToiletsList; } - debugPrint("map lenght: ${adaptedToiletsMap.length}"); - return adaptedToiletsMap; } diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart index ff9cf8ea..6cf08905 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart @@ -6,6 +6,9 @@ import "../../../../../config/ui_config.dart"; import "../../../../../theme/app_theme.dart"; import "../../../../../utils/context_extensions.dart"; import "../../../../../widgets/detail_views/detail_view_app_bar.dart"; +import "../../../../../widgets/my_cached_image.dart"; +import "../../../../../widgets/my_point_widget.dart"; +import "../../../presentation/widgets/digital_guide_nav_link.dart"; import "../data/models/adapted_toilet.dart"; @RoutePage() @@ -24,31 +27,123 @@ class AdaptedToiletDetailView extends ConsumerWidget { ), body: Padding( padding: const EdgeInsets.symmetric( - horizontal: DigitalGuideConfig.heightMedium, + horizontal: DigitalGuideConfig.heightBig, ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - context.localize.adapted_toilet_description, - style: context.textTheme.title.copyWith(fontSize: 18), + child: CustomScrollView( + slivers: [ + SliverList( + delegate: SliverChildListDelegate([ + Text( + () { + switch (adaptedToilet.hasAdditionalPurpose) { + case 1: + return context.localize.adapted_toilet_description; + case 2: + return context.localize.adapted_toilet_description_men; + case 3: + return context + .localize.adapted_toilet_description_women; + default: + return context.localize.adapted_toilet_description; + } + }(), + style: context.textTheme.title.copyWith(fontSize: 18), + ), + const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + if (adaptedToilet.translations.plTranslation.comment.isNotEmpty) + MyPointWidget( + text: adaptedToilet.translations.plTranslation.comment, + ), + MyPointWidget( + text: adaptedToilet.translations.plTranslation.location, + ), + if (adaptedToilet + .translations.plTranslation.numberOfCabins.isNotEmpty) + MyPointWidget( + text: + adaptedToilet.translations.plTranslation.numberOfCabins, + ), + MyPointWidget( + text: adaptedToilet + .translations.plTranslation.toiletDescription, + ), + if (!adaptedToilet.isAccessAccessibleForPwd) + MyPointWidget( + text: adaptedToilet.translations.plTranslation + .isAccessAccessibleForPwdComment, + ), + if (adaptedToilet.isNeedAuthorization != "Unknown") + MyPointWidget( + text: adaptedToilet.isNeedAuthorization == "True" + ? context.localize.adapted_toilet_authorization( + adaptedToilet.translations.plTranslation + .isNeedAuthorizationComment, + ) + : context.localize.adapted_toilet_no_authorization, + ), + if (adaptedToilet.translations.plTranslation + .isAreaAllowingMovementInFrontEntranceComment.isNotEmpty) + MyPointWidget( + text: adaptedToilet.translations.plTranslation + .isAreaAllowingMovementInFrontEntranceComment, + ), + MyPointWidget( + text: (adaptedToilet.isEntranceGraphicallyMarked && + adaptedToilet.translations.plTranslation + .isEntranceGraphicallyMarkedComment.isNotEmpty) + ? context.localize.adapted_toilet_graphically_marked( + adaptedToilet.translations.plTranslation + .isEntranceGraphicallyMarkedComment, + ) + : context.localize.adapted_toilet_not_graphically_marked, + ), + MyPointWidget( + text: adaptedToilet.isMarked + ? context.localize.adapted_toilet_is_marked( + adaptedToilet + .translations.plTranslation.isMarkedComment, + ) + : context.localize.adapted_toilet_is_not_marked, + ), + const SizedBox(height: DigitalGuideConfig.heightBig), + ListView.separated( + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return DigitalGuideNavLink( + onTap: () {}, + text: context.localize.doors, + ); + }, + itemCount: adaptedToilet.doorsIndices.length, + separatorBuilder: (context, index) => const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + shrinkWrap: true, + ), + const SizedBox( + height: DigitalGuideConfig.heightBig, + ), + if (adaptedToilet.imagesURLs.isNotEmpty) + Text( + context.localize.images, + style: context.textTheme.title.copyWith(fontSize: 28), + ), + Column( + children: adaptedToilet.imagesURLs.map((imageURL) { + return Padding( + padding: + const EdgeInsets.all(DigitalGuideConfig.heightMedium), + child: MyCachedImage(imageURL), + ); + }).toList(), + ), + const SizedBox( + height: DigitalGuideConfig.heightBig, + ), + ]), ), - const SizedBox( - height: DigitalGuideConfig.heightMedium, - ), - Text( - "• ${adaptedToilet.translations.plTranslation.location}", - style: context.textTheme.body.copyWith(fontSize: 16), - ), - Text( - "• ${adaptedToilet.translations.plTranslation.numberOfCabins}", - style: context.textTheme.body.copyWith(fontSize: 16), - ), - if (!adaptedToilet.isAccessAccessibleForPwd) - Text( - "• ${adaptedToilet.translations.plTranslation.isAccessAccessibleForPwdComment}", - style: context.textTheme.body.copyWith(fontSize: 16), - ), ], ), ), diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index 6dfd5544..06c24fbe 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -20,11 +20,8 @@ class AdaptedToiletsExpansionTileContent extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - debugPrint("AdaptedToiletsExpansionTileContent"); final asyncAdaptedToilets = ref .watch(GetAdaptedToiltesProvider(digitalGuideResponseExtended.levels)); - debugPrint("After fetching data"); - debugPrint("asyncAdaptedToilets: ${asyncAdaptedToilets.value}"); return asyncAdaptedToilets.when( data: (adaptedToiletsData) => _AdaptedToiletsExpansionTileContent( levels: digitalGuideResponseExtended.levels @@ -72,7 +69,7 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { style: context.textTheme.title, ), const SizedBox( - height: DigitalGuideConfig.heightMedium, + height: DigitalGuideConfig.heightSmall, ), ListView.separated( physics: const NeverScrollableScrollPhysics(), @@ -82,7 +79,20 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { adaptedToiletsData[level.id]![index], ); }, - text: context.localize.adapted_toilet_description, + text: () { + switch (adaptedToiletsData[level.id]![index] + .hasAdditionalPurpose) { + case 1: + return context.localize.adapted_toilet_description; + case 2: + return context.localize.adapted_toilet_description_men; + case 3: + return context + .localize.adapted_toilet_description_women; + default: + return context.localize.adapted_toilet_description; + } + }(), ), separatorBuilder: (context, index) => const SizedBox( height: DigitalGuideConfig.heightMedium, @@ -90,6 +100,9 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { itemCount: adaptedToiletsData[level.id]!.length, shrinkWrap: true, ), + const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), ], ); }).toList(), diff --git a/lib/l10n/app_pl.arb b/lib/l10n/app_pl.arb index d1fa555c..853a7b89 100644 --- a/lib/l10n/app_pl.arb +++ b/lib/l10n/app_pl.arb @@ -164,6 +164,8 @@ "elevators" : "Windy", "adapted_toilets" : "Toalety dostosowane", "adapted_toilet_description": "Toaleta dla osób z niepełnosprawnościami", + "adapted_toilet_description_men": "Toaleta dla mężczyzn z niepełnosprawnościami", + "adapted_toilet_description_women": "Toaleta dla kobiet z niepełnosprawnościami", "micro_navigation" : "Mikronawigacja", "building_structure" : "Struktura budynku", "room_information" : "Pomieszczenia", @@ -211,5 +213,38 @@ "sks_chart_title" : "Przybliżona liczba osób w Strefie Kultury Studenckiej", "number_of_people" : "Liczba osób", "evacuation_text": "Ewakuacja i pierwsza pomoc", - "digital_guide": "Przeowdnik" + "digital_guide": "Przewodnik", + "adapted_toilet_authorization": "Toaleta jest dostępna wyłącznie dla osób uprawnionych. {comment}", + "@adapted_toilet_authorization": { + "description": "Adapted toilet needs authorization with ending from API", + "placeholders": { + "comment": { + "type": "String" + } + } + }, + "adapted_toilet_no_authorization": "Wejście do toalety nie wymaga żadnych specjalnych uprawnień.", + "adapted_toilet_graphically_marked": "Wejście do toalety jest dobrze oznakowane graficznie, za pomocą: {comment}", + "@adapted_toilet_graphically_marked": { + "description": "Adapted toilet is graphically marked info with ending from API", + "placeholders": { + "comment": { + "type": "String", + "example": "piktogramów toalety damskiej i dostosowanej do potrzeb osób z niepełnosprawnością na drzwiach wejściowych do ogólnodostępnej toalety damskiej." + } + } + }, + "adapted_toilet_not_graphically_marked": "Wejście do toalety nie jest oznakowane graficznie.", + "adapted_toilet_is_marked": "Lokalizacja toalety jest oznaczona za pomocą informacji kierunkowej. {comment}", + "@adapted_toilet_is_marked": { + "description": "Adapted toilet is marked info with ending from API", + "placeholders": { + "comment": { + "type": "String" + } + } + }, + "adapted_toilet_is_not_marked": "Lokalizacja toalety nie jest oznaczona za pomocą informacji kierunkowej.", + "images": "Zdjęcia", + "doors": "Drzwi" } diff --git a/lib/widgets/my_point_widget.dart b/lib/widgets/my_point_widget.dart new file mode 100644 index 00000000..9d636fdb --- /dev/null +++ b/lib/widgets/my_point_widget.dart @@ -0,0 +1,39 @@ +import "package:flutter/material.dart"; + +import "../config/ui_config.dart"; +import "../theme/app_theme.dart"; + +class MyPointWidget extends StatelessWidget { + const MyPointWidget({ + required this.text, + }); + + final String text; + + @override + Widget build(BuildContext context) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Padding( + padding: EdgeInsets.only(right: DigitalGuideConfig.heightSmall), + child: Text( + "•", + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.only(top: DigitalGuideConfig.heightSmall), + child: Text( + text, + style: context.textTheme.body.copyWith(fontSize: 16), + maxLines: 100, + overflow: TextOverflow.ellipsis, + ), + ), + ), + ], + ); + } +} From e15d7b4bda6da0edb1124d59235affe8995146e0 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Fri, 27 Dec 2024 15:46:09 +0100 Subject: [PATCH 03/20] refractor: move checking whether there are adapted toilets to digital guide response class --- .../models/digital_guide_response_extended.dart | 14 ++++++++++++++ .../widgets/digital_guide_features_section.dart | 12 +----------- .../home_view/widgets/science_clubs_section.dart | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart index 6e723228..7d7f02a9 100644 --- a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart +++ b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart @@ -47,6 +47,20 @@ class DigitalGuideResponseExtended { final DigitalGuideEvacuation evacuation; final IList entraces; + bool areAdaptedToilets() { + return levels.fold( + 0, + (levelValue, levelElement) => + levelValue + + levelElement.regions.fold( + 0, + (regionValue, regionElement) => + regionValue + regionElement.adaptedToiletsIndices.length, + ), + ) > + 0; + } + factory DigitalGuideResponseExtended.fromDigitalGuideResponse({ required DigitalGuideResponse digitalGuideResponse, required String? imageUrl, diff --git a/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart b/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart index 06085bc7..56d417f4 100644 --- a/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart +++ b/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart @@ -54,17 +54,7 @@ class DigitalGuideFeaturesSection extends StatelessWidget { title: context.localize.elevators, content: [LocalizationExpansionTileContent()], ), - if (digitalGuideResponseExtended.levels.fold( - 0, - (levelValue, levelElement) => - levelValue + - levelElement.regions.fold( - 0, - (regionValue, regionElement) => - regionValue + regionElement.adaptedToiletsIndices.length, - ), - ) > - 0) + if (digitalGuideResponseExtended.areAdaptedToilets()) ( title: context.localize.adapted_toilets, content: [ diff --git a/lib/features/home_view/widgets/science_clubs_section.dart b/lib/features/home_view/widgets/science_clubs_section.dart index edababc7..ca6aa4a0 100644 --- a/lib/features/home_view/widgets/science_clubs_section.dart +++ b/lib/features/home_view/widgets/science_clubs_section.dart @@ -20,7 +20,7 @@ class ScienceClubsSection extends ConsumerWidget { children: [ FilledButton( onPressed: () async { - await ref.navigateDigitalGuide(313); + await ref.navigateDigitalGuide(319); }, child: const Text("navigate to digital guide mock"), ), From 0c45e56f1b58a04b5b3566b3be69baf30286dbe8 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Fri, 27 Dec 2024 15:50:02 +0100 Subject: [PATCH 04/20] refractor: switch expression in an extension instead of swtich statement --- .../data/models/adapted_toilet.dart | 14 ++++++++++++++ .../adapted_toilet_detail_view.dart | 14 +------------- .../adapted_toilets_expansion_tile_content.dart | 17 ++--------------- 3 files changed, 17 insertions(+), 28 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart index 1cc3151e..54464341 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart @@ -1,3 +1,6 @@ +import "package:flutter/material.dart"; + +import "../../../../../../utils/context_extensions.dart"; import "adapted_toilet_not_full.dart"; class AdaptedToilet { @@ -38,3 +41,14 @@ class AdaptedToilet { ); } } + +extension AdaptedToiletLocalization on AdaptedToilet { + String getDescription(BuildContext context) { + return switch (hasAdditionalPurpose) { + 1 => context.localize.adapted_toilet_description, + 2 => context.localize.adapted_toilet_description_men, + 3 => context.localize.adapted_toilet_description_women, + _ => context.localize.adapted_toilet_description, + }; + } +} diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart index 6cf08905..2fee391e 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart @@ -34,19 +34,7 @@ class AdaptedToiletDetailView extends ConsumerWidget { SliverList( delegate: SliverChildListDelegate([ Text( - () { - switch (adaptedToilet.hasAdditionalPurpose) { - case 1: - return context.localize.adapted_toilet_description; - case 2: - return context.localize.adapted_toilet_description_men; - case 3: - return context - .localize.adapted_toilet_description_women; - default: - return context.localize.adapted_toilet_description; - } - }(), + adaptedToilet.getDescription(context), style: context.textTheme.title.copyWith(fontSize: 18), ), const SizedBox( diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index 06c24fbe..5c91da1e 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -3,7 +3,6 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; import "../../../../../config/ui_config.dart"; import "../../../../../theme/app_theme.dart"; -import "../../../../../utils/context_extensions.dart"; import "../../../../../widgets/my_error_widget.dart"; import "../../../../navigator/utils/navigation_commands.dart"; import "../../../data/models/digital_guide_response_extended.dart"; @@ -79,20 +78,8 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { adaptedToiletsData[level.id]![index], ); }, - text: () { - switch (adaptedToiletsData[level.id]![index] - .hasAdditionalPurpose) { - case 1: - return context.localize.adapted_toilet_description; - case 2: - return context.localize.adapted_toilet_description_men; - case 3: - return context - .localize.adapted_toilet_description_women; - default: - return context.localize.adapted_toilet_description; - } - }(), + text: adaptedToiletsData[level.id]![index] + .getDescription(context), ), separatorBuilder: (context, index) => const SizedBox( height: DigitalGuideConfig.heightMedium, From 0f0e1e09a6a43da1fd0e5c9f431f1ac03ff7725a Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Sat, 28 Dec 2024 00:44:20 +0100 Subject: [PATCH 05/20] fix: use text theme --- lib/widgets/my_point_widget.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/widgets/my_point_widget.dart b/lib/widgets/my_point_widget.dart index 9d636fdb..060e23fc 100644 --- a/lib/widgets/my_point_widget.dart +++ b/lib/widgets/my_point_widget.dart @@ -1,9 +1,10 @@ import "package:flutter/material.dart"; +import "package:flutter_riverpod/flutter_riverpod.dart"; import "../config/ui_config.dart"; import "../theme/app_theme.dart"; -class MyPointWidget extends StatelessWidget { +class MyPointWidget extends ConsumerWidget { const MyPointWidget({ required this.text, }); @@ -11,15 +12,15 @@ class MyPointWidget extends StatelessWidget { final String text; @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const Padding( - padding: EdgeInsets.only(right: DigitalGuideConfig.heightSmall), + Padding( + padding: const EdgeInsets.only(right: DigitalGuideConfig.heightSmall), child: Text( "•", - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + style: context.textTheme.title.copyWith(fontSize: 24), ), ), Expanded( From fbbb969423afb2f00dc23d2122bfd568676180f5 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Mon, 30 Dec 2024 16:11:40 +0100 Subject: [PATCH 06/20] fix: _stringToBool lowercase --- .../digital_guide_view/data/models/digital_guide_response.dart | 2 +- .../adapted_toilets/data/models/adapted_toilet_not_full.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/features/digital_guide_view/data/models/digital_guide_response.dart b/lib/features/digital_guide_view/data/models/digital_guide_response.dart index fb0d3611..1f5dc889 100644 --- a/lib/features/digital_guide_view/data/models/digital_guide_response.dart +++ b/lib/features/digital_guide_view/data/models/digital_guide_response.dart @@ -131,7 +131,7 @@ class Region with _$Region { } bool _stringToBool(String value) { - return value == "True"; + return value.toLowerCase() == "true"; } List _formatPhoneNumbers(String phoneNumber) { diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart index e699b4bb..581a11e4 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart @@ -58,7 +58,7 @@ class AdaptedToiletTranslation with _$AdaptedToiletTranslation { } bool _stringToBool(String str) { - return str == "True"; + return str.toLowerCase() == "true"; } int _stringToInt(String str) { From 27e94415e122e8b0dd09e878fb32d2ca8704bb07 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Mon, 30 Dec 2024 16:43:53 +0100 Subject: [PATCH 07/20] refractor: List to IList --- .../adapted_toilets_expansion_tile_content.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index 5c91da1e..196b5fca 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -1,3 +1,4 @@ +import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter/material.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; @@ -29,7 +30,7 @@ class AdaptedToiletsExpansionTileContent extends ConsumerWidget { adaptedToiletsData.containsKey(level.id) && adaptedToiletsData[level.id]!.isNotEmpty, ) - .toList(), + .toIList(), adaptedToiletsData: adaptedToiletsData, ), error: (error, stackTrace) => MyErrorWidget(error), @@ -46,7 +47,7 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { required this.adaptedToiletsData, }); - final List levels; + final IList levels; final Map> adaptedToiletsData; @override @@ -78,8 +79,7 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { adaptedToiletsData[level.id]![index], ); }, - text: adaptedToiletsData[level.id]![index] - .getDescription(context), + text: adaptedToiletsData[level.id]![index].getDescription(context), ), separatorBuilder: (context, index) => const SizedBox( height: DigitalGuideConfig.heightMedium, From 9feae8f8cc5d99d6c75fc319eef97a75acee3ecc Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Mon, 30 Dec 2024 16:54:34 +0100 Subject: [PATCH 08/20] refractor: avoid null assertations --- ...dapted_toilets_expansion_tile_content.dart | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index 196b5fca..3c69d4b5 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -73,18 +73,23 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { ), ListView.separated( physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) => DigitalGuideNavLink( - onTap: () async { - await ref.navigateAdaptedToiletDetails( - adaptedToiletsData[level.id]![index], + itemBuilder: (context, index) { + final levelData = adaptedToiletsData[level.id]; + return levelData == null + ? const SizedBox() + : DigitalGuideNavLink( + onTap: () async { + await ref.navigateAdaptedToiletDetails( + levelData[index], + ); + }, + text: levelData[index].getDescription(context), ); - }, - text: adaptedToiletsData[level.id]![index].getDescription(context), - ), + }, separatorBuilder: (context, index) => const SizedBox( height: DigitalGuideConfig.heightMedium, ), - itemCount: adaptedToiletsData[level.id]!.length, + itemCount: adaptedToiletsData[level.id]?.length ?? 0, shrinkWrap: true, ), const SizedBox( From c619620fec54302a16373676eaf64482c339236f Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Mon, 30 Dec 2024 17:05:27 +0100 Subject: [PATCH 09/20] refractor: implement IsNeedAuthorizationEnum in adapted toilet model --- .../data/models/adapted_toilet.dart | 2 +- .../data/models/adapted_toilet_not_full.dart | 14 +++++++++++++- .../presentation/adapted_toilet_detail_view.dart | 7 +++++-- .../adapted_toilets_expansion_tile_content.dart | 16 ++++++++-------- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart index 54464341..c44574ed 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.dart @@ -18,7 +18,7 @@ class AdaptedToilet { final AdaptedToiletTranslations translations; final bool isAccessAccessibleForPwd; final int hasAdditionalPurpose; - final String isNeedAuthorization; + final IsNeedAuthorizationEnum isNeedAuthorization; final bool isEntranceGraphicallyMarked; final bool isMarked; final List imagesURLs; diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart index 581a11e4..2e58e1fd 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet_not_full.dart @@ -13,7 +13,8 @@ class AdaptedToiletNotFull with _$AdaptedToiletNotFull { required bool isAccessAccessibleForPwd, @JsonKey(name: "has_additional_purpose", fromJson: _stringToInt) required int hasAdditionalPurpose, - @JsonKey(name: "is_need_authorization") required String isNeedAuthorization, + @JsonKey(name: "is_need_authorization", fromJson: isNeedAuthorizationToEnum) + required IsNeedAuthorizationEnum isNeedAuthorization, @JsonKey(name: "is_entrance_graphically_marked", fromJson: _stringToBool) required bool isEntranceGraphicallyMarked, @JsonKey(name: "is_marked", fromJson: _stringToBool) required bool isMarked, @@ -64,3 +65,14 @@ bool _stringToBool(String str) { int _stringToInt(String str) { return int.tryParse(str) ?? 1; } + +IsNeedAuthorizationEnum isNeedAuthorizationToEnum(String str) { + return switch (str.toLowerCase()) { + "true" => IsNeedAuthorizationEnum.yes, + "false" => IsNeedAuthorizationEnum.no, + "unknown" => IsNeedAuthorizationEnum.unknown, + _ => IsNeedAuthorizationEnum.unknown, + }; +} + +enum IsNeedAuthorizationEnum { yes, no, unknown } diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart index 2fee391e..7051af4e 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart @@ -10,6 +10,7 @@ import "../../../../../widgets/my_cached_image.dart"; import "../../../../../widgets/my_point_widget.dart"; import "../../../presentation/widgets/digital_guide_nav_link.dart"; import "../data/models/adapted_toilet.dart"; +import "../data/models/adapted_toilet_not_full.dart"; @RoutePage() class AdaptedToiletDetailView extends ConsumerWidget { @@ -62,9 +63,11 @@ class AdaptedToiletDetailView extends ConsumerWidget { text: adaptedToilet.translations.plTranslation .isAccessAccessibleForPwdComment, ), - if (adaptedToilet.isNeedAuthorization != "Unknown") + if (adaptedToilet.isNeedAuthorization != + IsNeedAuthorizationEnum.unknown) MyPointWidget( - text: adaptedToilet.isNeedAuthorization == "True" + text: adaptedToilet.isNeedAuthorization == + IsNeedAuthorizationEnum.yes ? context.localize.adapted_toilet_authorization( adaptedToilet.translations.plTranslation .isNeedAuthorizationComment, diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index 3c69d4b5..6286fa5f 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -76,15 +76,15 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { itemBuilder: (context, index) { final levelData = adaptedToiletsData[level.id]; return levelData == null - ? const SizedBox() - : DigitalGuideNavLink( - onTap: () async { - await ref.navigateAdaptedToiletDetails( - levelData[index], + ? const SizedBox() + : DigitalGuideNavLink( + onTap: () async { + await ref.navigateAdaptedToiletDetails( + levelData[index], + ); + }, + text: levelData[index].getDescription(context), ); - }, - text: levelData[index].getDescription(context), - ); }, separatorBuilder: (context, index) => const SizedBox( height: DigitalGuideConfig.heightMedium, From eb1544d0ff1f3ee6bf02edb1a3434a1a6019bcf2 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Sat, 4 Jan 2025 13:45:55 +0100 Subject: [PATCH 10/20] refractor: simplify ununderstandable function --- .../digital_guide_response_extended.dart | 22 +++++++++---------- ...dapted_toilets_expansion_tile_content.dart | 3 --- .../widgets/science_clubs_section.dart | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart index 7d7f02a9..d78016ed 100644 --- a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart +++ b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart @@ -48,17 +48,17 @@ class DigitalGuideResponseExtended { final IList entraces; bool areAdaptedToilets() { - return levels.fold( - 0, - (levelValue, levelElement) => - levelValue + - levelElement.regions.fold( - 0, - (regionValue, regionElement) => - regionValue + regionElement.adaptedToiletsIndices.length, - ), - ) > - 0; + + for(final level in levels) { + for(final region in level.regions) { + if(region.adaptedToiletsIndices.isNotEmpty) { + return true; + } + } + } + + return false; + } factory DigitalGuideResponseExtended.fromDigitalGuideResponse({ diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index 6286fa5f..303db9f4 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -92,9 +92,6 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { itemCount: adaptedToiletsData[level.id]?.length ?? 0, shrinkWrap: true, ), - const SizedBox( - height: DigitalGuideConfig.heightMedium, - ), ], ); }).toList(), diff --git a/lib/features/home_view/widgets/science_clubs_section.dart b/lib/features/home_view/widgets/science_clubs_section.dart index ca6aa4a0..edababc7 100644 --- a/lib/features/home_view/widgets/science_clubs_section.dart +++ b/lib/features/home_view/widgets/science_clubs_section.dart @@ -20,7 +20,7 @@ class ScienceClubsSection extends ConsumerWidget { children: [ FilledButton( onPressed: () async { - await ref.navigateDigitalGuide(319); + await ref.navigateDigitalGuide(313); }, child: const Text("navigate to digital guide mock"), ), From ab11f586a712364db3c682b2c33df0a0ec66e4fe Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Sat, 4 Jan 2025 13:58:15 +0100 Subject: [PATCH 11/20] refactor: avoid null asserations --- .../data/repository/adapted_toilets_repository.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart index 8d9539cc..17e2c168 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart @@ -37,9 +37,9 @@ Future>> getAdaptedToiltes( final imagesURLsFutures = adaptedToiletNotFull.imagesIndices.map((imageID) async { final imageURL = await ref.watch(GetImageUrlProvider(imageID).future); - return imageURL!; + return imageURL; }); - final imagesURLs = await Future.wait(imagesURLsFutures); + final imagesURLs = (await Future.wait(imagesURLsFutures)).whereType().toList(); return AdaptedToilet.create( adaptedToiletNotFull: adaptedToiletNotFull, imagesURLs: imagesURLs, From 22df51bfc7cb512d3c4bb0892c8b83d8c249d7c3 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Sat, 4 Jan 2025 14:04:56 +0100 Subject: [PATCH 12/20] refactor: IMap instread of Map --- .../data/repository/adapted_toilets_repository.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart index 17e2c168..0225c586 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart @@ -1,3 +1,4 @@ +import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:riverpod_annotation/riverpod_annotation.dart"; @@ -11,7 +12,7 @@ import "../models/adapted_toilet_not_full.dart"; part "adapted_toilets_repository.g.dart"; @riverpod -Future>> getAdaptedToiltes( +Future>> getAdaptedToiltes( Ref ref, List levels, ) async { @@ -51,5 +52,5 @@ Future>> getAdaptedToiltes( adaptedToiletsMap[level.id] = adaptedToiletsList; } - return adaptedToiletsMap; + return adaptedToiletsMap.lock; } From 8612111596161b31116a578dfbc12f3d3ec3bdf4 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Sat, 4 Jan 2025 14:43:20 +0100 Subject: [PATCH 13/20] refactor: minor improvements --- .../data/repository/adapted_toilets_repository.dart | 4 ++-- .../presentation/adapted_toilet_detail_view.dart | 4 +--- .../presentation/adapted_toilets_expansion_tile_content.dart | 4 +++- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart index 0225c586..7329e81f 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart @@ -23,8 +23,8 @@ Future>> getAdaptedToiltes( final Map> adaptedToiletsMap = {}; for (final level in levels) { - final adaptedToiletsIDs = level.regions - .fold([], (list, region) => list + region.adaptedToiletsIndices); + + final adaptedToiletsIDs = level.regions.expand((region) => region.adaptedToiletsIndices).toList(); final adaptedToiletsIterable = adaptedToiletsIDs.map((adaptedTouiletID) async { diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart index 7051af4e..0e9c8086 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart @@ -23,9 +23,7 @@ class AdaptedToiletDetailView extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return Scaffold( - appBar: DetailViewAppBar( - actions: const [], - ), + appBar: DetailViewAppBar(), body: Padding( padding: const EdgeInsets.symmetric( horizontal: DigitalGuideConfig.heightBig, diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index 303db9f4..24a9d299 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -48,7 +48,9 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { }); final IList levels; - final Map> adaptedToiletsData; + + // map: level id (keys) -> adapted toilets instances (values) + final IMap> adaptedToiletsData; @override Widget build(BuildContext context, WidgetRef ref) { From d4b9065e83c82e1bd9a3e5ab0e004d216cb74302 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Sat, 4 Jan 2025 15:07:27 +0100 Subject: [PATCH 14/20] refactor: improvements --- .../data/models/digital_guide_response_extended.dart | 2 +- .../presentation/widgets/digital_guide_features_section.dart | 2 +- .../data/repository/adapted_toilets_repository.dart | 4 ++-- .../presentation/adapted_toilets_expansion_tile_content.dart | 5 ++++- lib/widgets/my_point_widget.dart | 2 +- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart index d78016ed..18f85687 100644 --- a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart +++ b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart @@ -47,7 +47,7 @@ class DigitalGuideResponseExtended { final DigitalGuideEvacuation evacuation; final IList entraces; - bool areAdaptedToilets() { + bool hasAdaptedToilets() { for(final level in levels) { for(final region in level.regions) { diff --git a/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart b/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart index 56d417f4..25cd75a1 100644 --- a/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart +++ b/lib/features/digital_guide_view/presentation/widgets/digital_guide_features_section.dart @@ -54,7 +54,7 @@ class DigitalGuideFeaturesSection extends StatelessWidget { title: context.localize.elevators, content: [LocalizationExpansionTileContent()], ), - if (digitalGuideResponseExtended.areAdaptedToilets()) + if (digitalGuideResponseExtended.hasAdaptedToilets()) ( title: context.localize.adapted_toilets, content: [ diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart index 7329e81f..47c17082 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart @@ -12,7 +12,7 @@ import "../models/adapted_toilet_not_full.dart"; part "adapted_toilets_repository.g.dart"; @riverpod -Future>> getAdaptedToiltes( +Future>> adaptedToiletsRepository( Ref ref, List levels, ) async { @@ -23,7 +23,7 @@ Future>> getAdaptedToiltes( final Map> adaptedToiletsMap = {}; for (final level in levels) { - + final adaptedToiletsIDs = level.regions.expand((region) => region.adaptedToiletsIndices).toList(); final adaptedToiletsIterable = diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index 24a9d299..3d227780 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -21,7 +21,7 @@ class AdaptedToiletsExpansionTileContent extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final asyncAdaptedToilets = ref - .watch(GetAdaptedToiltesProvider(digitalGuideResponseExtended.levels)); + .watch(AdaptedToiletsRepositoryProvider(digitalGuideResponseExtended.levels)); return asyncAdaptedToilets.when( data: (adaptedToiletsData) => _AdaptedToiletsExpansionTileContent( levels: digitalGuideResponseExtended.levels @@ -94,6 +94,9 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { itemCount: adaptedToiletsData[level.id]?.length ?? 0, shrinkWrap: true, ), + const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), ], ); }).toList(), diff --git a/lib/widgets/my_point_widget.dart b/lib/widgets/my_point_widget.dart index 060e23fc..9d696b49 100644 --- a/lib/widgets/my_point_widget.dart +++ b/lib/widgets/my_point_widget.dart @@ -29,7 +29,7 @@ class MyPointWidget extends ConsumerWidget { child: Text( text, style: context.textTheme.body.copyWith(fontSize: 16), - maxLines: 100, + // maxLines: 100, overflow: TextOverflow.ellipsis, ), ), From e89c8e4405cbb5186544fa34e126d9a8b3d3fbb3 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Sat, 4 Jan 2025 15:38:19 +0100 Subject: [PATCH 15/20] refactor: divide digital guide repo separating levels repo --- .../repository/digital_guide_repository.dart | 45 +------------------ .../data/repository/levels_repository.dart | 37 +++++++++++++++ 2 files changed, 39 insertions(+), 43 deletions(-) create mode 100644 lib/features/digital_guide_view/data/repository/levels_repository.dart diff --git a/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart b/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart index 9561c5f2..7f8def7e 100644 --- a/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart +++ b/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart @@ -8,6 +8,7 @@ import "../../tabs/entraces/data/repository/entraces_repository.dart"; import "../../tabs/evacuation/data/repository/evacuation_repository.dart"; import "../models/digital_guide_response.dart"; import "../models/digital_guide_response_extended.dart"; +import "levels_repository.dart"; part "digital_guide_repository.g.dart"; @@ -25,7 +26,7 @@ Future getDigitalGuideDataExtended( final entraces = await ref .watch(getDigitalGuideEntracesProvider(digitalGuideResponse.id).future); final levels = await ref - .watch(GetLevelsProvider(digitalGuideResponse.levelsIndices).future); + .watch(LevelsRespositoryProvider(digitalGuideResponse.levelsIndices).future); return DigitalGuideResponseExtended.fromDigitalGuideResponse( digitalGuideResponse: digitalGuideResponse, imageUrl: imageUrl, @@ -57,48 +58,6 @@ Future getImageUrl(Ref ref, int id) async { return imageUrl; } -@riverpod -Future> getLevels(Ref ref, List levelsIndices) async { - final dio = ref.read(restClientProvider); - dio.options.headers["Authorization"] = - "Token ${Env.digitalGuideAuthorizationToken}"; - - final levelsFutures = levelsIndices.map((levelID) async { - final levelResponse = - await dio.get("${Env.digitalGuideUrl}/levels/$levelID"); - final levelNotFull = - LevelNotFull.fromJson(levelResponse.data as Map); - final regionsFutures = levelNotFull.regionIndices.map((regionID) async { - final regionResponse = - await dio.get("${Env.digitalGuideUrl}/regions/$regionID"); - return Region.fromJson(regionResponse.data as Map); - }).toList(); - final regions = await Future.wait(regionsFutures); - return Level.create(levelNotFull: levelNotFull, regions: regions); - }).toList(); - - final levelsList = await Future.wait(levelsFutures); - levelsList.sort( - (level1, level2) => level1.floorNumber.compareTo(level2.floorNumber), - ); - - return levelsList; -} - -@riverpod -Future> getRegions(Ref ref, List regionsIndices) async { - final dio = ref.read(restClientProvider); - dio.options.headers["Authorization"] = - "Token ${Env.digitalGuideAuthorizationToken}"; - - final regionsIterable = regionsIndices.map((id) async { - final response = await dio.get("${Env.digitalGuideUrl}/regions/$id"); - return Region.fromJson(response.data as Map); - }); - - return Future.wait(regionsIterable); -} - @riverpod Future getDigitalGuideBuildingData( Ref ref, diff --git a/lib/features/digital_guide_view/data/repository/levels_repository.dart b/lib/features/digital_guide_view/data/repository/levels_repository.dart new file mode 100644 index 00000000..1e848966 --- /dev/null +++ b/lib/features/digital_guide_view/data/repository/levels_repository.dart @@ -0,0 +1,37 @@ +import "package:flutter_riverpod/flutter_riverpod.dart"; +import "package:riverpod_annotation/riverpod_annotation.dart"; + +import "../../../../api_base_rest/client/dio_client.dart"; +import "../../../../config/env.dart"; +import "../models/digital_guide_response.dart"; +import "../models/digital_guide_response_extended.dart"; + +part "levels_repository.g.dart"; + +@riverpod +Future> levelsRespository(Ref ref, List levelsIndices) async { + final dio = ref.read(restClientProvider); + dio.options.headers["Authorization"] = + "Token ${Env.digitalGuideAuthorizationToken}"; + + final levelsFutures = levelsIndices.map((levelID) async { + final levelResponse = + await dio.get("${Env.digitalGuideUrl}/levels/$levelID"); + final levelNotFull = + LevelNotFull.fromJson(levelResponse.data as Map); + final regionsFutures = levelNotFull.regionIndices.map((regionID) async { + final regionResponse = + await dio.get("${Env.digitalGuideUrl}/regions/$regionID"); + return Region.fromJson(regionResponse.data as Map); + }).toList(); + final regions = await Future.wait(regionsFutures); + return Level.create(levelNotFull: levelNotFull, regions: regions); + }).toList(); + + final levelsList = await Future.wait(levelsFutures); + levelsList.sort( + (level1, level2) => level1.floorNumber.compareTo(level2.floorNumber), + ); + + return levelsList; +} From 07a724aa1de000655fa5358a60066df822774852 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Sat, 4 Jan 2025 15:58:39 +0100 Subject: [PATCH 16/20] refactor: convert list delegate to builder based delegate --- .../adapted_toilet_detail_view.dart | 212 +++++++++--------- 1 file changed, 112 insertions(+), 100 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart index 0e9c8086..86e9ba0a 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart @@ -22,6 +22,97 @@ class AdaptedToiletDetailView extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { + + final List points = [ + Text( + adaptedToilet.getDescription(context), + style: context.textTheme.title.copyWith(fontSize: 18), + ), + const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + if (adaptedToilet.translations.plTranslation.comment.isNotEmpty) + MyPointWidget( + text: adaptedToilet.translations.plTranslation.comment, + ), + MyPointWidget( + text: adaptedToilet.translations.plTranslation.location, + ), + if (adaptedToilet + .translations.plTranslation.numberOfCabins.isNotEmpty) + MyPointWidget( + text: + adaptedToilet.translations.plTranslation.numberOfCabins, + ), + MyPointWidget( + text: adaptedToilet + .translations.plTranslation.toiletDescription, + ), + if (!adaptedToilet.isAccessAccessibleForPwd) + MyPointWidget( + text: adaptedToilet.translations.plTranslation + .isAccessAccessibleForPwdComment, + ), + if (adaptedToilet.isNeedAuthorization != + IsNeedAuthorizationEnum.unknown) + MyPointWidget( + text: adaptedToilet.isNeedAuthorization == + IsNeedAuthorizationEnum.yes + ? context.localize.adapted_toilet_authorization( + adaptedToilet.translations.plTranslation + .isNeedAuthorizationComment, + ) + : context.localize.adapted_toilet_no_authorization, + ), + if (adaptedToilet.translations.plTranslation + .isAreaAllowingMovementInFrontEntranceComment.isNotEmpty) + MyPointWidget( + text: adaptedToilet.translations.plTranslation + .isAreaAllowingMovementInFrontEntranceComment, + ), + MyPointWidget( + text: (adaptedToilet.isEntranceGraphicallyMarked && + adaptedToilet.translations.plTranslation + .isEntranceGraphicallyMarkedComment.isNotEmpty) + ? context.localize.adapted_toilet_graphically_marked( + adaptedToilet.translations.plTranslation + .isEntranceGraphicallyMarkedComment, + ) + : context.localize.adapted_toilet_not_graphically_marked, + ), + MyPointWidget( + text: adaptedToilet.isMarked + ? context.localize.adapted_toilet_is_marked( + adaptedToilet + .translations.plTranslation.isMarkedComment, + ) + : context.localize.adapted_toilet_is_not_marked, + ), + const SizedBox(height: DigitalGuideConfig.heightBig), + ListView.separated( + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return DigitalGuideNavLink( + onTap: () {}, + text: context.localize.doors, + ); + }, + itemCount: adaptedToilet.doorsIndices.length, + separatorBuilder: (context, index) => const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + shrinkWrap: true, + ), + const SizedBox( + height: DigitalGuideConfig.heightBig, + ), + if (adaptedToilet.imagesURLs.isNotEmpty) + Text( + context.localize.images, + style: context.textTheme.title.copyWith(fontSize: 28), + ), + ]; + return Scaffold( appBar: DetailViewAppBar(), body: Padding( @@ -31,107 +122,28 @@ class AdaptedToiletDetailView extends ConsumerWidget { child: CustomScrollView( slivers: [ SliverList( - delegate: SliverChildListDelegate([ - Text( - adaptedToilet.getDescription(context), - style: context.textTheme.title.copyWith(fontSize: 18), - ), - const SizedBox( - height: DigitalGuideConfig.heightMedium, - ), - if (adaptedToilet.translations.plTranslation.comment.isNotEmpty) - MyPointWidget( - text: adaptedToilet.translations.plTranslation.comment, - ), - MyPointWidget( - text: adaptedToilet.translations.plTranslation.location, - ), - if (adaptedToilet - .translations.plTranslation.numberOfCabins.isNotEmpty) - MyPointWidget( - text: - adaptedToilet.translations.plTranslation.numberOfCabins, - ), - MyPointWidget( - text: adaptedToilet - .translations.plTranslation.toiletDescription, - ), - if (!adaptedToilet.isAccessAccessibleForPwd) - MyPointWidget( - text: adaptedToilet.translations.plTranslation - .isAccessAccessibleForPwdComment, - ), - if (adaptedToilet.isNeedAuthorization != - IsNeedAuthorizationEnum.unknown) - MyPointWidget( - text: adaptedToilet.isNeedAuthorization == - IsNeedAuthorizationEnum.yes - ? context.localize.adapted_toilet_authorization( - adaptedToilet.translations.plTranslation - .isNeedAuthorizationComment, - ) - : context.localize.adapted_toilet_no_authorization, - ), - if (adaptedToilet.translations.plTranslation - .isAreaAllowingMovementInFrontEntranceComment.isNotEmpty) - MyPointWidget( - text: adaptedToilet.translations.plTranslation - .isAreaAllowingMovementInFrontEntranceComment, - ), - MyPointWidget( - text: (adaptedToilet.isEntranceGraphicallyMarked && - adaptedToilet.translations.plTranslation - .isEntranceGraphicallyMarkedComment.isNotEmpty) - ? context.localize.adapted_toilet_graphically_marked( - adaptedToilet.translations.plTranslation - .isEntranceGraphicallyMarkedComment, - ) - : context.localize.adapted_toilet_not_graphically_marked, - ), - MyPointWidget( - text: adaptedToilet.isMarked - ? context.localize.adapted_toilet_is_marked( - adaptedToilet - .translations.plTranslation.isMarkedComment, - ) - : context.localize.adapted_toilet_is_not_marked, - ), - const SizedBox(height: DigitalGuideConfig.heightBig), - ListView.separated( - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return DigitalGuideNavLink( - onTap: () {}, - text: context.localize.doors, - ); - }, - itemCount: adaptedToilet.doorsIndices.length, - separatorBuilder: (context, index) => const SizedBox( - height: DigitalGuideConfig.heightMedium, - ), - shrinkWrap: true, - ), - const SizedBox( - height: DigitalGuideConfig.heightBig, - ), - if (adaptedToilet.imagesURLs.isNotEmpty) - Text( - context.localize.images, - style: context.textTheme.title.copyWith(fontSize: 28), - ), - Column( - children: adaptedToilet.imagesURLs.map((imageURL) { - return Padding( - padding: - const EdgeInsets.all(DigitalGuideConfig.heightMedium), - child: MyCachedImage(imageURL), + delegate: SliverChildBuilderDelegate( + (context, index) { + if(index < points.length) { + return points[index]; + } + + if(index == points.length && adaptedToilet.imagesURLs.isNotEmpty) { + return Column( + children: adaptedToilet.imagesURLs.map((imageURL) { + return Padding( + padding: + const EdgeInsets.all(DigitalGuideConfig.heightMedium), + child: MyCachedImage(imageURL), + ); + }).toList(), ); - }).toList(), - ), - const SizedBox( - height: DigitalGuideConfig.heightBig, - ), - ]), + } + + return null; + }, + childCount: points.length + (adaptedToilet.imagesURLs.isNotEmpty ? 1 : 0), + ), ), ], ), From 499842a12f1a63dd13197370e7d97caf0758552a Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Sat, 4 Jan 2025 23:44:37 +0100 Subject: [PATCH 17/20] refactor: AdaptedToiletLevel widget --- .../adapted_toilet_detail_view.dart | 29 ++--- ...dapted_toilets_expansion_tile_content.dart | 123 +++++++++++++----- 2 files changed, 99 insertions(+), 53 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart index 86e9ba0a..b0ec15e4 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart @@ -121,28 +121,21 @@ class AdaptedToiletDetailView extends ConsumerWidget { ), child: CustomScrollView( slivers: [ + SliverList( + delegate: SliverChildBuilderDelegate( + (context, index) => points[index], + childCount: points.length, + ), + ), SliverList( delegate: SliverChildBuilderDelegate( (context, index) { - if(index < points.length) { - return points[index]; - } - - if(index == points.length && adaptedToilet.imagesURLs.isNotEmpty) { - return Column( - children: adaptedToilet.imagesURLs.map((imageURL) { - return Padding( - padding: - const EdgeInsets.all(DigitalGuideConfig.heightMedium), - child: MyCachedImage(imageURL), - ); - }).toList(), - ); - } - - return null; + return Padding( + padding: const EdgeInsets.all(DigitalGuideConfig.heightMedium), + child: MyCachedImage(adaptedToilet.imagesURLs[index]), + ); }, - childCount: points.length + (adaptedToilet.imagesURLs.isNotEmpty ? 1 : 0), + childCount: adaptedToilet.imagesURLs.length, ), ), ], diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index 3d227780..4c721f80 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -63,44 +63,97 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: levels.map((level) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - level.translations.plTranslation.name, - style: context.textTheme.title, - ), - const SizedBox( - height: DigitalGuideConfig.heightSmall, - ), - ListView.separated( - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - final levelData = adaptedToiletsData[level.id]; - return levelData == null - ? const SizedBox() - : DigitalGuideNavLink( - onTap: () async { - await ref.navigateAdaptedToiletDetails( - levelData[index], - ); - }, - text: levelData[index].getDescription(context), - ); - }, - separatorBuilder: (context, index) => const SizedBox( - height: DigitalGuideConfig.heightMedium, - ), - itemCount: adaptedToiletsData[level.id]?.length ?? 0, - shrinkWrap: true, - ), - const SizedBox( - height: DigitalGuideConfig.heightMedium, - ), - ], + return AdaptedToiletLevel( + level: level, + adaptedToilets: adaptedToiletsData[level.id] ?? [], ); + // return Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // level.translations.plTranslation.name, + // style: context.textTheme.title, + // ), + // const SizedBox( + // height: DigitalGuideConfig.heightSmall, + // ), + // ListView.separated( + // physics: const NeverScrollableScrollPhysics(), + // itemBuilder: (context, index) { + // final levelData = adaptedToiletsData[level.id]; + // return levelData == null + // ? const SizedBox() + // : DigitalGuideNavLink( + // onTap: () async { + // await ref.navigateAdaptedToiletDetails( + // levelData[index], + // ); + // }, + // text: levelData[index].getDescription(context), + // ); + // }, + // separatorBuilder: (context, index) => const SizedBox( + // height: DigitalGuideConfig.heightMedium, + // ), + // itemCount: adaptedToiletsData[level.id]?.length ?? 0, + // shrinkWrap: true, + // ), + // const SizedBox( + // height: DigitalGuideConfig.heightMedium, + // ), + // ], + // ); }).toList(), ), ); } } + +class AdaptedToiletLevel extends ConsumerWidget { + const AdaptedToiletLevel({ + required this.level, + required this.adaptedToilets, + }); + + final Level level; + final List adaptedToilets; + + @override + Widget build(BuildContext context, WidgetRef ref) { + return adaptedToilets.isEmpty + ? const SizedBox() + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + level.translations.plTranslation.name, + style: context.textTheme.title, + ), + const SizedBox( + height: DigitalGuideConfig.heightSmall, + ), + ListView.separated( + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return DigitalGuideNavLink( + onTap: () async { + await ref.navigateAdaptedToiletDetails( + adaptedToilets[index], + ); + }, + text: adaptedToilets[index].getDescription(context), + ); + }, + separatorBuilder: (context, index) => const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + itemCount: adaptedToilets.length, + shrinkWrap: true, + ), + const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + ], + ); + } +} From d4e873abab997bfc5bbcfb16235c079c42ba9920 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Sun, 5 Jan 2025 00:01:26 +0100 Subject: [PATCH 18/20] fix: format --- .../digital_guide_response_extended.dart | 8 +- .../repository/digital_guide_repository.dart | 5 +- .../adapted_toilets_repository.dart | 7 +- .../adapted_toilet_detail_view.dart | 30 ++--- ...dapted_toilets_expansion_tile_content.dart | 107 ++++++------------ 5 files changed, 57 insertions(+), 100 deletions(-) diff --git a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart index 18f85687..29fc1a69 100644 --- a/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart +++ b/lib/features/digital_guide_view/data/models/digital_guide_response_extended.dart @@ -48,17 +48,15 @@ class DigitalGuideResponseExtended { final IList entraces; bool hasAdaptedToilets() { - - for(final level in levels) { - for(final region in level.regions) { - if(region.adaptedToiletsIndices.isNotEmpty) { + for (final level in levels) { + for (final region in level.regions) { + if (region.adaptedToiletsIndices.isNotEmpty) { return true; } } } return false; - } factory DigitalGuideResponseExtended.fromDigitalGuideResponse({ diff --git a/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart b/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart index 7f8def7e..c036dd7f 100644 --- a/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart +++ b/lib/features/digital_guide_view/data/repository/digital_guide_repository.dart @@ -25,8 +25,9 @@ Future getDigitalGuideDataExtended( await ref.watch(getDigitalGuideEvacuationProvider(id).future); final entraces = await ref .watch(getDigitalGuideEntracesProvider(digitalGuideResponse.id).future); - final levels = await ref - .watch(LevelsRespositoryProvider(digitalGuideResponse.levelsIndices).future); + final levels = await ref.watch( + LevelsRespositoryProvider(digitalGuideResponse.levelsIndices).future, + ); return DigitalGuideResponseExtended.fromDigitalGuideResponse( digitalGuideResponse: digitalGuideResponse, imageUrl: imageUrl, diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart index 47c17082..23e904a4 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart @@ -23,8 +23,8 @@ Future>> adaptedToiletsRepository( final Map> adaptedToiletsMap = {}; for (final level in levels) { - - final adaptedToiletsIDs = level.regions.expand((region) => region.adaptedToiletsIndices).toList(); + final adaptedToiletsIDs = + level.regions.expand((region) => region.adaptedToiletsIndices).toList(); final adaptedToiletsIterable = adaptedToiletsIDs.map((adaptedTouiletID) async { @@ -40,7 +40,8 @@ Future>> adaptedToiletsRepository( final imageURL = await ref.watch(GetImageUrlProvider(imageID).future); return imageURL; }); - final imagesURLs = (await Future.wait(imagesURLsFutures)).whereType().toList(); + final imagesURLs = + (await Future.wait(imagesURLsFutures)).whereType().toList(); return AdaptedToilet.create( adaptedToiletNotFull: adaptedToiletNotFull, imagesURLs: imagesURLs, diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart index b0ec15e4..1bb40082 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart @@ -22,7 +22,6 @@ class AdaptedToiletDetailView extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final List points = [ Text( adaptedToilet.getDescription(context), @@ -38,29 +37,24 @@ class AdaptedToiletDetailView extends ConsumerWidget { MyPointWidget( text: adaptedToilet.translations.plTranslation.location, ), - if (adaptedToilet - .translations.plTranslation.numberOfCabins.isNotEmpty) + if (adaptedToilet.translations.plTranslation.numberOfCabins.isNotEmpty) MyPointWidget( - text: - adaptedToilet.translations.plTranslation.numberOfCabins, + text: adaptedToilet.translations.plTranslation.numberOfCabins, ), MyPointWidget( - text: adaptedToilet - .translations.plTranslation.toiletDescription, + text: adaptedToilet.translations.plTranslation.toiletDescription, ), if (!adaptedToilet.isAccessAccessibleForPwd) MyPointWidget( - text: adaptedToilet.translations.plTranslation - .isAccessAccessibleForPwdComment, + text: adaptedToilet + .translations.plTranslation.isAccessAccessibleForPwdComment, ), - if (adaptedToilet.isNeedAuthorization != - IsNeedAuthorizationEnum.unknown) + if (adaptedToilet.isNeedAuthorization != IsNeedAuthorizationEnum.unknown) MyPointWidget( - text: adaptedToilet.isNeedAuthorization == - IsNeedAuthorizationEnum.yes + text: adaptedToilet.isNeedAuthorization == IsNeedAuthorizationEnum.yes ? context.localize.adapted_toilet_authorization( - adaptedToilet.translations.plTranslation - .isNeedAuthorizationComment, + adaptedToilet + .translations.plTranslation.isNeedAuthorizationComment, ) : context.localize.adapted_toilet_no_authorization, ), @@ -83,8 +77,7 @@ class AdaptedToiletDetailView extends ConsumerWidget { MyPointWidget( text: adaptedToilet.isMarked ? context.localize.adapted_toilet_is_marked( - adaptedToilet - .translations.plTranslation.isMarkedComment, + adaptedToilet.translations.plTranslation.isMarkedComment, ) : context.localize.adapted_toilet_is_not_marked, ), @@ -131,7 +124,8 @@ class AdaptedToiletDetailView extends ConsumerWidget { delegate: SliverChildBuilderDelegate( (context, index) { return Padding( - padding: const EdgeInsets.all(DigitalGuideConfig.heightMedium), + padding: + const EdgeInsets.all(DigitalGuideConfig.heightMedium), child: MyCachedImage(adaptedToilet.imagesURLs[index]), ); }, diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index 4c721f80..f3817f6f 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -20,8 +20,9 @@ class AdaptedToiletsExpansionTileContent extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { - final asyncAdaptedToilets = ref - .watch(AdaptedToiletsRepositoryProvider(digitalGuideResponseExtended.levels)); + final asyncAdaptedToilets = ref.watch( + AdaptedToiletsRepositoryProvider(digitalGuideResponseExtended.levels), + ); return asyncAdaptedToilets.when( data: (adaptedToiletsData) => _AdaptedToiletsExpansionTileContent( levels: digitalGuideResponseExtended.levels @@ -67,42 +68,6 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { level: level, adaptedToilets: adaptedToiletsData[level.id] ?? [], ); - // return Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // Text( - // level.translations.plTranslation.name, - // style: context.textTheme.title, - // ), - // const SizedBox( - // height: DigitalGuideConfig.heightSmall, - // ), - // ListView.separated( - // physics: const NeverScrollableScrollPhysics(), - // itemBuilder: (context, index) { - // final levelData = adaptedToiletsData[level.id]; - // return levelData == null - // ? const SizedBox() - // : DigitalGuideNavLink( - // onTap: () async { - // await ref.navigateAdaptedToiletDetails( - // levelData[index], - // ); - // }, - // text: levelData[index].getDescription(context), - // ); - // }, - // separatorBuilder: (context, index) => const SizedBox( - // height: DigitalGuideConfig.heightMedium, - // ), - // itemCount: adaptedToiletsData[level.id]?.length ?? 0, - // shrinkWrap: true, - // ), - // const SizedBox( - // height: DigitalGuideConfig.heightMedium, - // ), - // ], - // ); }).toList(), ), ); @@ -121,39 +86,37 @@ class AdaptedToiletLevel extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return adaptedToilets.isEmpty - ? const SizedBox() - : Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - level.translations.plTranslation.name, - style: context.textTheme.title, - ), - const SizedBox( - height: DigitalGuideConfig.heightSmall, - ), - ListView.separated( - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - return DigitalGuideNavLink( - onTap: () async { - await ref.navigateAdaptedToiletDetails( - adaptedToilets[index], - ); - }, - text: adaptedToilets[index].getDescription(context), - ); - }, - separatorBuilder: (context, index) => const SizedBox( - height: DigitalGuideConfig.heightMedium, - ), - itemCount: adaptedToilets.length, - shrinkWrap: true, - ), - const SizedBox( - height: DigitalGuideConfig.heightMedium, - ), - ], - ); + ? const SizedBox() + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + level.translations.plTranslation.name, + style: context.textTheme.title, + ), + const SizedBox( + height: DigitalGuideConfig.heightSmall, + ), + ListView.separated( + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) => DigitalGuideNavLink( + onTap: () async { + await ref.navigateAdaptedToiletDetails( + adaptedToilets[index], + ); + }, + text: adaptedToilets[index].getDescription(context), + ), + separatorBuilder: (context, index) => const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + itemCount: adaptedToilets.length, + shrinkWrap: true, + ), + const SizedBox( + height: DigitalGuideConfig.heightMedium, + ), + ], + ); } } From 73173b5a4ca675e5c0daf19ea61cbbe83e0a8579 Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Thu, 9 Jan 2025 16:23:19 +0100 Subject: [PATCH 19/20] refactor: List to IList and formatting --- .../adapted_toilets_expansion_tile_content.dart | 6 ++++-- lib/widgets/my_point_widget.dart | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index f3817f6f..d1b6a5e5 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -66,7 +66,9 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { children: levels.map((level) { return AdaptedToiletLevel( level: level, - adaptedToilets: adaptedToiletsData[level.id] ?? [], + adaptedToilets: adaptedToiletsData[level.id] != null + ? adaptedToiletsData[level.id]!.lock + : IList(), ); }).toList(), ), @@ -81,7 +83,7 @@ class AdaptedToiletLevel extends ConsumerWidget { }); final Level level; - final List adaptedToilets; + final IList adaptedToilets; @override Widget build(BuildContext context, WidgetRef ref) { diff --git a/lib/widgets/my_point_widget.dart b/lib/widgets/my_point_widget.dart index 9d696b49..060e23fc 100644 --- a/lib/widgets/my_point_widget.dart +++ b/lib/widgets/my_point_widget.dart @@ -29,7 +29,7 @@ class MyPointWidget extends ConsumerWidget { child: Text( text, style: context.textTheme.body.copyWith(fontSize: 16), - // maxLines: 100, + maxLines: 100, overflow: TextOverflow.ellipsis, ), ), From 9aeae6b2a3f7eb649c82111fec80dd48bcc11faf Mon Sep 17 00:00:00 2001 From: 24bartixx Date: Thu, 9 Jan 2025 21:39:34 +0100 Subject: [PATCH 20/20] refactor: change maps and lists to immutable --- .../data/repository/adapted_toilets_repository.dart | 6 +++--- .../adapted_toilets_expansion_tile_content.dart | 6 ++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart index 23e904a4..e9b908d7 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/data/repository/adapted_toilets_repository.dart @@ -12,7 +12,7 @@ import "../models/adapted_toilet_not_full.dart"; part "adapted_toilets_repository.g.dart"; @riverpod -Future>> adaptedToiletsRepository( +Future>> adaptedToiletsRepository( Ref ref, List levels, ) async { @@ -20,7 +20,7 @@ Future>> adaptedToiletsRepository( dio.options.headers["Authorization"] = "Token ${Env.digitalGuideAuthorizationToken}"; - final Map> adaptedToiletsMap = {}; + final Map> adaptedToiletsMap = {}; for (final level in levels) { final adaptedToiletsIDs = @@ -50,7 +50,7 @@ Future>> adaptedToiletsRepository( final adaptedToiletsList = await Future.wait(adaptedToiletsIterable); - adaptedToiletsMap[level.id] = adaptedToiletsList; + adaptedToiletsMap[level.id] = adaptedToiletsList.lock; } return adaptedToiletsMap.lock; diff --git a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart index d1b6a5e5..88238ca7 100644 --- a/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart +++ b/lib/features/digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilets_expansion_tile_content.dart @@ -51,7 +51,7 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { final IList levels; // map: level id (keys) -> adapted toilets instances (values) - final IMap> adaptedToiletsData; + final IMap> adaptedToiletsData; @override Widget build(BuildContext context, WidgetRef ref) { @@ -66,9 +66,7 @@ class _AdaptedToiletsExpansionTileContent extends ConsumerWidget { children: levels.map((level) { return AdaptedToiletLevel( level: level, - adaptedToilets: adaptedToiletsData[level.id] != null - ? adaptedToiletsData[level.id]!.lock - : IList(), + adaptedToilets: adaptedToiletsData[level.id] ?? IList(), ); }).toList(), ),