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:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user