1
0
mirror of https://github.com/flutter/samples.git synced 2026-05-22 15:09:07 +00:00

Compass app (#2446)

This commit is contained in:
Eric Windmill
2024-09-27 18:49:27 -04:00
committed by GitHub
parent fcf2552cda
commit 46b5a26b26
326 changed files with 53272 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
// Copyright 2024 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:logging/logging.dart';
import '../../../data/repositories/activity/activity_repository.dart';
import '../../../data/repositories/booking/booking_repository.dart';
import '../../../data/repositories/destination/destination_repository.dart';
import '../../../utils/result.dart';
import '../../models/activity/activity.dart';
import '../../models/booking/booking.dart';
import '../../models/destination/destination.dart';
import '../../models/itinerary_config/itinerary_config.dart';
/// UseCase for creating [Booking] objects from [ItineraryConfig].
///
/// Fetches [Destination] and [Activity] objects from repositories,
/// checks if dates are set and creates a [Booking] object.
class BookingCreateUseCase {
BookingCreateUseCase({
required DestinationRepository destinationRepository,
required ActivityRepository activityRepository,
required BookingRepository bookingRepository,
}) : _destinationRepository = destinationRepository,
_activityRepository = activityRepository,
_bookingRepository = bookingRepository;
final DestinationRepository _destinationRepository;
final ActivityRepository _activityRepository;
final BookingRepository _bookingRepository;
final _log = Logger('BookingCreateUseCase');
/// Create [Booking] from a stored [ItineraryConfig]
Future<Result<Booking>> createFrom(ItineraryConfig itineraryConfig) async {
// Get Destination object from repository
if (itineraryConfig.destination == null) {
_log.warning('Destination is not set');
return Result.error(Exception('Destination is not set'));
}
final destinationResult =
await _fetchDestination(itineraryConfig.destination!);
if (destinationResult is Error<Destination>) {
_log.warning('Error fetching destination: ${destinationResult.error}');
return Result.error(destinationResult.error);
}
_log.fine('Destination loaded: ${destinationResult.asOk.value.ref}');
// Get Activity objects from repository
if (itineraryConfig.activities.isEmpty) {
_log.warning('Activities are not set');
return Result.error(Exception('Activities are not set'));
}
final activitiesResult = await _activityRepository.getByDestination(
itineraryConfig.destination!,
);
if (activitiesResult is Error<List<Activity>>) {
_log.warning('Error fetching activities: ${activitiesResult.error}');
return Result.error(activitiesResult.error);
}
final activities = activitiesResult.asOk.value
.where(
(activity) => itineraryConfig.activities.contains(activity.ref),
)
.toList();
_log.fine('Activities loaded (${activities.length})');
// Check if dates are set
if (itineraryConfig.startDate == null || itineraryConfig.endDate == null) {
_log.warning('Dates are not set');
return Result.error(Exception('Dates are not set'));
}
final booking = Booking(
startDate: itineraryConfig.startDate!,
endDate: itineraryConfig.endDate!,
destination: destinationResult.asOk.value,
activity: activities,
);
final saveBookingResult = await _bookingRepository.createBooking(booking);
switch (saveBookingResult) {
case Ok<void>():
_log.fine('Booking saved successfully');
break;
case Error<void>():
_log.warning('Failed to save booking', saveBookingResult.error);
return Result.error(saveBookingResult.error);
}
// Create Booking object
return Result.ok(booking);
}
Future<Result<Destination>> _fetchDestination(String destinationRef) async {
final result = await _destinationRepository.getDestinations();
switch (result) {
case Ok<List<Destination>>():
final destination = result.value
.firstWhere((destination) => destination.ref == destinationRef);
return Ok(destination);
case Error<List<Destination>>():
return Result.error(result.error);
}
}
}

View File

@@ -0,0 +1,46 @@
// Copyright 2024 The Flutter team. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:share_plus/share_plus.dart';
import '../../../utils/result.dart';
import '../../../ui/core/ui/date_format_start_end.dart';
import '../../models/booking/booking.dart';
typedef ShareFunction = Future<void> Function(String text);
/// UseCase for sharing a booking.
class BookingShareUseCase {
BookingShareUseCase._(this._share);
/// Create a [BookingShareUseCase] that uses `share_plus` package.
factory BookingShareUseCase.withSharePlus() =>
BookingShareUseCase._(Share.share);
/// Create a [BookingShareUseCase] with a custom share function.
factory BookingShareUseCase.custom(ShareFunction share) =>
BookingShareUseCase._(share);
final ShareFunction _share;
final _log = Logger('BookingShareUseCase');
Future<Result<void>> shareBooking(Booking booking) async {
final text = 'Trip to ${booking.destination.name}\n'
'on ${dateFormatStartEnd(DateTimeRange(start: booking.startDate, end: booking.endDate))}\n'
'Activities:\n'
'${booking.activity.map((a) => ' - ${a.name}').join('\n')}.';
_log.info('Sharing booking: $text');
try {
await _share(text);
_log.fine('Shared booking');
return Result.ok(null);
} on Exception catch (error) {
_log.severe('Failed to share booking', error);
return Result.error(error);
}
}
}