Skip to content

Commit

Permalink
Merge branch 'main' into feat(digital-guide)/add-micronavigation-info
Browse files Browse the repository at this point in the history
  • Loading branch information
thesun901 authored Jan 17, 2025
2 parents 3bf7b08 + c9500a2 commit 6989415
Show file tree
Hide file tree
Showing 9 changed files with 276 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import "../../tabs/amenities/presentation/amenities_expansion_tile_content.dart"
import "../../tabs/evacuation/evacuation_widget.dart";
import "../../tabs/localization/presentation/localization_expansion_tile_content.dart";
import "../../tabs/micronavigation/presentation/micronavigation_expansion_tile_content.dart";
import "../../tabs/rooms/presentation/digital_guide_rooms_expansion_tile_content.dart";
import "../../tabs/surrounding/presentation/surroundings_expansion_tile_content.dart";

typedef TileContent = ({String title, List<Widget> content});
Expand Down Expand Up @@ -87,7 +88,11 @@ class DigitalGuideFeaturesSection extends ConsumerWidget {
),
(
title: context.localize.room_information,
content: [LocalizationExpansionTileContent()],
content: [
DigitalGuideRoomExpansionTileContent(
digitalGuideResponse: digitalGuideData,
),
],
),
(
title: context.localize.evacuation,
Expand Down
11 changes: 8 additions & 3 deletions lib/features/digital_guide_view/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,18 @@

# Used endpoints
1) Building data and image
* /general_info/data/repository/digita_guide_repository.dart
* /general_info/data/repository/digital_guide_repository.dart
* DIGITAL_GUIDE_URL/buildings/{id}
* DIGITAL_GUIDE_URL/images/{id}
2) Surroundings data
* tabs/surrounding/data/repository/surrounding_repository.dart
* DIGITAL_GUIDE_URL/surroundings/{id}

3) Micronavigation data
* /tabs/micronavigation/data/repository/micronavigation_repository.dart
* DIGITAL_GUIDE_URL_MICRONAVIGATION/beaconplus/?location={external_id}
* Note that endpoint above is different than usual one and uses external_id from digital_guide_response. Additionaly it is unprotected, so for now it is not being added to .env
* DIGITAL_GUIDE_ADDONS_URL/beaconplus/?location={external_id}

4) Rooms data
* /rooms/data/repository/rooms_repository.dart
* DIGITAL_GUIDE_URL/rooms/{id}

Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import "package:freezed_annotation/freezed_annotation.dart";

part "digital_guide_room.freezed.dart";

part "digital_guide_room.g.dart";

@freezed
class DigitalGuideRoom with _$DigitalGuideRoom {
const factory DigitalGuideRoom({
required int id,
required DigitalGuideTranslationsRoom translations,
@JsonKey(name: "images") required List<int>? imagesIds,
}) = _DigitalGuideRoom;

factory DigitalGuideRoom.fromJson(Map<String, dynamic> json) =>
_$DigitalGuideRoomFromJson(json);
}

@freezed
class DigitalGuideTranslationsRoom with _$DigitalGuideTranslationsRoom {
const factory DigitalGuideTranslationsRoom({
required DigitalGuideTranslationRoom pl,
}) = _DigitalGuideTranslationsRoom;

factory DigitalGuideTranslationsRoom.fromJson(Map<String, dynamic> json) =>
_$DigitalGuideTranslationsRoomFromJson(json);
}

@freezed
class DigitalGuideTranslationRoom with _$DigitalGuideTranslationRoom {
@JsonSerializable(fieldRename: FieldRename.snake)
const factory DigitalGuideTranslationRoom({
required String name,
required String roomPurpose,
required String location,
required String workingDaysAndHours,
required String areEntrancesComment,
required String isOneLevelFloorComment,
required String arePlacesForWheelchairsComment,
required String comment,
}) = _DigitalGuideTranslationRoom;

factory DigitalGuideTranslationRoom.fromJson(Map<String, dynamic> json) =>
_$DigitalGuideTranslationRoomFromJson(json);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:riverpod_annotation/riverpod_annotation.dart";

import "../../../../data/api/digital_guide_get_and_cache.dart";
import "../../../../data/models/digital_guide_response.dart";
import "../models/digital_guide_room.dart";

part "rooms_repository.g.dart";

@riverpod
Future<IList<DigitalGuideRoom>> roomsRepository(
Ref ref,
DigitalGuideResponse building,
) async {
final String endpoint = "rooms/?building=${building.id}";

return ref.getAndCacheDataFromDigitalGuide(
endpoint,
(List<dynamic> json) => json
.whereType<Map<String, dynamic>>()
.map(DigitalGuideRoom.fromJson)
.toIList(),
onRetry: () => ref.invalidateSelf(),
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import "package:auto_route/annotations.dart";
import "package:fast_immutable_collections/fast_immutable_collections.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 "../../../../../utils/ilist_nonempty.dart";
import "../../../../../widgets/detail_views/detail_view_app_bar.dart";
import "../../../presentation/widgets/accessibility_button.dart";
import "../../../presentation/widgets/bullet_list.dart";
import "../../../presentation/widgets/digital_guide_nav_link.dart";
import "../../../presentation/widgets/digital_guide_photo_row.dart";
import "../data/models/digital_guide_room.dart";

@RoutePage()
class DigitalGuideRoomDetailView extends ConsumerWidget {
const DigitalGuideRoomDetailView({required this.room});

final DigitalGuideRoom room;

@override
Widget build(BuildContext context, WidgetRef ref) {
final roomInformation = room.translations.pl;
final widgets = [
Text(
roomInformation.name,
style: context.textTheme.headline.copyWith(fontSize: 18),
),
const SizedBox(height: DigitalGuideConfig.heightTiny),
Text(
roomInformation.roomPurpose,
style: context.textTheme.headline
.copyWith(fontSize: 12, fontWeight: FontWeight.normal),
),
if (roomInformation.workingDaysAndHours.isNotEmpty)
const SizedBox(height: DigitalGuideConfig.heightMedium),
if (roomInformation.workingDaysAndHours.isNotEmpty)
Text(
"${context.localize.working_hours}:",
style: context.textTheme.headline,
),
if (roomInformation.workingDaysAndHours.isNotEmpty)
const SizedBox(height: DigitalGuideConfig.heightSmall),
Text(
roomInformation.workingDaysAndHours,
style: context.textTheme.body.copyWith(fontSize: 16),
),
if (roomInformation.workingDaysAndHours.isNotEmpty)
const SizedBox(height: DigitalGuideConfig.heightMedium),
Text(
context.localize.key_information,
style: context.textTheme.headline,
),
const SizedBox(height: DigitalGuideConfig.heightSmall),
BulletList(
items: [
roomInformation.location,
roomInformation.comment,
roomInformation.areEntrancesComment,
roomInformation.isOneLevelFloorComment,
roomInformation.arePlacesForWheelchairsComment,
roomInformation.isOneLevelFloorComment,
].toIList(),
),
if (room.imagesIds != null && room.imagesIds!.isNotEmpty)
const SizedBox(
height: DigitalGuideConfig.heightMedium,
),
DigitalGuidePhotoRow(imagesIDs: room.imagesIds.toIList()),
const SizedBox(
height: DigitalGuideConfig.heightMedium,
),
DigitalGuideNavLink(
onTap: () {},
text: context.localize.doors,
),
const SizedBox(
height: DigitalGuideConfig.heightMedium,
),
DigitalGuideNavLink(
onTap: () {},
text: context.localize.platforms,
),
const SizedBox(
height: DigitalGuideConfig.heightMedium,
),
DigitalGuideNavLink(
onTap: () {},
text: context.localize.stairs,
),
];
return Scaffold(
appBar: DetailViewAppBar(
actions: [AccessibilityButton()],
),
body: Padding(
padding: const EdgeInsets.all(DigitalGuideConfig.paddingMedium),
child: ListView.builder(
physics: const NeverScrollableScrollPhysics(),
itemCount: widgets.length,
shrinkWrap: true,
itemBuilder: (context, index) => widgets[index],
),
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter/material.dart";
import "package:flutter_riverpod/flutter_riverpod.dart";

import "../../../../../config/ui_config.dart";
import "../../../../../widgets/my_error_widget.dart";
import "../../../../navigator/utils/navigation_commands.dart";
import "../../../data/models/digital_guide_response.dart";
import "../../../presentation/widgets/digital_guide_nav_link.dart";
import "../data/models/digital_guide_room.dart";
import "../data/repository/rooms_repository.dart";

class DigitalGuideRoomExpansionTileContent extends ConsumerWidget {
const DigitalGuideRoomExpansionTileContent({
required this.digitalGuideResponse,
});

final DigitalGuideResponse digitalGuideResponse;

@override
Widget build(BuildContext context, WidgetRef ref) {
final roomsInBuilding =
ref.watch(roomsRepositoryProvider(digitalGuideResponse));
return roomsInBuilding.when(
data: (data) => _DigitalGuideRoomExpansionTileContent(rooms: data),
error: (error, _) => MyErrorWidget(error),
loading: () => const Center(
child: CircularProgressIndicator(),
),
);
}
}

class _DigitalGuideRoomExpansionTileContent extends ConsumerWidget {
const _DigitalGuideRoomExpansionTileContent({required this.rooms});

final IList<DigitalGuideRoom> rooms;

@override
Widget build(BuildContext context, WidgetRef ref) {
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: DigitalGuideConfig.paddingMedium,
vertical: DigitalGuideConfig.paddingMedium,
),
child: ListView.separated(
physics: const NeverScrollableScrollPhysics(),
separatorBuilder: (context, index) => const SizedBox(
height: DigitalGuideConfig.heightMedium,
),
itemCount: rooms.length,
shrinkWrap: true,
itemBuilder: (context, index) => DigitalGuideNavLink(
onTap: () async {
await ref.navigateRoomDetails(
rooms[index],
);
},
text: rooms[index].translations.pl.name,
),
),
);
}
}
6 changes: 6 additions & 0 deletions lib/features/navigator/app_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import "../digital_guide_view/tabs/adapted_toilets/data/models/adapted_toilet.da
import "../digital_guide_view/tabs/adapted_toilets/presentation/adapted_toilet_detail_view.dart";
import "../digital_guide_view/tabs/micronavigation/data/models/micronavigation_response.dart";
import "../digital_guide_view/tabs/micronavigation/presentation/micronavigation_detail_view.dart";
import "../digital_guide_view/tabs/rooms/data/models/digital_guide_room.dart";
import "../digital_guide_view/tabs/rooms/presentation/digital_guide_room_detail_view.dart";
import "../guide_detail_view/guide_detail_view.dart";
import "../guide_view/guide_view.dart";
import "../home_view/home_view.dart";
Expand All @@ -23,6 +25,7 @@ import "../sks-menu/presentation/sks_menu_screen.dart";
import "root_view.dart";

part "app_router.g.dart";

part "app_router.gr.dart";

class _NoTransitionRoute extends CustomRoute {
Expand Down Expand Up @@ -114,6 +117,9 @@ class AppRouter extends RootStackRouter {
path: "/digital-guide/:id/micronavigationDetails",
page: MicronavigationDetailRoute.page,
),
AutoRoute(
page: DigitalGuideRoomDetailRoute.page,
),
];
}

Expand Down
7 changes: 6 additions & 1 deletion lib/features/navigator/utils/navigation_commands.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ 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 "../../digital_guide_view/tabs/micronavigation/data/models/micronavigation_response.dart";
import "../../digital_guide_view/tabs/rooms/data/models/digital_guide_room.dart";
import "../../parkings_view/models/parking.dart";
import "../app_router.dart";
import "../navigation_controller.dart";

/// just a one place to gather implementation details of navigation flow
/// - for easy maintainance
/// - for easy maintenance
extension NavigationX on WidgetRef {
NavigationController get _router =>
read(navigationControllerProvider.notifier);
Expand Down Expand Up @@ -96,4 +97,8 @@ extension NavigationX on WidgetRef {
),
);
}

Future<void> navigateRoomDetails(DigitalGuideRoom room) async {
await _router.push(DigitalGuideRoomDetailRoute(room: room));
}
}
9 changes: 6 additions & 3 deletions lib/l10n/app_pl.arb
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@
"people_blind" : "niewidomych",
"people_with_motor_disability" : "posiadających dysfunkcje ruchu",
"people_with_high_sensory_sensitivity" : "o wysokiej wrażliwości sensorycznej",
"see_all_photos" : "Zobacz {photos, plural, =0{{photos} zdjęć} =1{{photos} zdjęcie} few{wszystkie {photos} zdjęcia} other{wszystkie {photos} zjęć}}",
"see_all_photos" : "Zobacz {photos, plural, =0{{photos} zdjęć} =1{{photos} zdjęcie} few{wszystkie {photos} zdjęcia} other{wszystkie {photos} zdjęć}}",
"are_dangerous_elements_comment_prefix" : "W otoczeniu budynku znajdują się następujące obiekty, które mogą stanowić zagrożenie: {text}",
"are_high_curbs_at_parking_space_for_pwd" : "Przy miejscach postojowych dla osób z niepełnosprawnościami {value, select, false{nie} other{}} znajduje się wysoki krawężnik. ",
"is_lit" : "Otoczenie budynku {value, select, false{nie} other{}} jest oświetlone po zmroku. ",
Expand All @@ -287,6 +287,9 @@
"communique" : "Komunikat",
"audio_message" : "Komunikat Dźwiękowy",
"audio_message_comment" : "Sygnał znacznika może różnić się tempem i brzmieniem",
"digital_guide" : "Cyfrowy Przewodnik"

"digital_guide" : "Cyfrowy Przewodnik",
"platforms" : "Podesty",
"stairs" : "Schody",
"key_information" : "Najważniejsze informacje",
"working_hours" : "Godziny otwarcia"
}

0 comments on commit 6989415

Please sign in to comment.