mirror of
https://github.com/flutter/samples.git
synced 2025-11-13 00:08:24 +00:00
Flutter 3.29 beta (#2571)
This commit is contained in:
@@ -16,8 +16,8 @@ class ActivitiesViewModel extends ChangeNotifier {
|
||||
ActivitiesViewModel({
|
||||
required ActivityRepository activityRepository,
|
||||
required ItineraryConfigRepository itineraryConfigRepository,
|
||||
}) : _activityRepository = activityRepository,
|
||||
_itineraryConfigRepository = itineraryConfigRepository {
|
||||
}) : _activityRepository = activityRepository,
|
||||
_itineraryConfigRepository = itineraryConfigRepository {
|
||||
loadActivities = Command0(_loadActivities)..execute();
|
||||
saveActivities = Command0(_saveActivities);
|
||||
}
|
||||
@@ -48,10 +48,7 @@ class ActivitiesViewModel extends ChangeNotifier {
|
||||
final result = await _itineraryConfigRepository.getItineraryConfig();
|
||||
switch (result) {
|
||||
case Error<ItineraryConfig>():
|
||||
_log.warning(
|
||||
'Failed to load stored ItineraryConfig',
|
||||
result.error,
|
||||
);
|
||||
_log.warning('Failed to load stored ItineraryConfig', result.error);
|
||||
return result;
|
||||
case Ok<ItineraryConfig>():
|
||||
}
|
||||
@@ -64,28 +61,37 @@ class ActivitiesViewModel extends ChangeNotifier {
|
||||
|
||||
_selectedActivities.addAll(result.value.activities);
|
||||
|
||||
final resultActivities =
|
||||
await _activityRepository.getByDestination(destinationRef);
|
||||
final resultActivities = await _activityRepository.getByDestination(
|
||||
destinationRef,
|
||||
);
|
||||
switch (resultActivities) {
|
||||
case Ok():
|
||||
{
|
||||
_daytimeActivities = resultActivities.value
|
||||
.where((activity) => [
|
||||
TimeOfDay.any,
|
||||
TimeOfDay.morning,
|
||||
TimeOfDay.afternoon,
|
||||
].contains(activity.timeOfDay))
|
||||
.toList();
|
||||
_daytimeActivities =
|
||||
resultActivities.value
|
||||
.where(
|
||||
(activity) => [
|
||||
TimeOfDay.any,
|
||||
TimeOfDay.morning,
|
||||
TimeOfDay.afternoon,
|
||||
].contains(activity.timeOfDay),
|
||||
)
|
||||
.toList();
|
||||
|
||||
_eveningActivities = resultActivities.value
|
||||
.where((activity) => [
|
||||
TimeOfDay.evening,
|
||||
TimeOfDay.night,
|
||||
].contains(activity.timeOfDay))
|
||||
.toList();
|
||||
_eveningActivities =
|
||||
resultActivities.value
|
||||
.where(
|
||||
(activity) => [
|
||||
TimeOfDay.evening,
|
||||
TimeOfDay.night,
|
||||
].contains(activity.timeOfDay),
|
||||
)
|
||||
.toList();
|
||||
|
||||
_log.fine('Activities (daytime: ${_daytimeActivities.length}, '
|
||||
'evening: ${_eveningActivities.length}) loaded');
|
||||
_log.fine(
|
||||
'Activities (daytime: ${_daytimeActivities.length}, '
|
||||
'evening: ${_eveningActivities.length}) loaded',
|
||||
);
|
||||
}
|
||||
case Error():
|
||||
{
|
||||
@@ -100,8 +106,9 @@ class ActivitiesViewModel extends ChangeNotifier {
|
||||
/// Add [Activity] to selected list.
|
||||
void addActivity(String activityRef) {
|
||||
assert(
|
||||
(_daytimeActivities + _eveningActivities)
|
||||
.any((activity) => activity.ref == activityRef),
|
||||
(_daytimeActivities + _eveningActivities).any(
|
||||
(activity) => activity.ref == activityRef,
|
||||
),
|
||||
"Activity $activityRef not found",
|
||||
);
|
||||
_selectedActivities.add(activityRef);
|
||||
@@ -112,8 +119,9 @@ class ActivitiesViewModel extends ChangeNotifier {
|
||||
/// Remove [Activity] from selected list.
|
||||
void removeActivity(String activityRef) {
|
||||
assert(
|
||||
(_daytimeActivities + _eveningActivities)
|
||||
.any((activity) => activity.ref == activityRef),
|
||||
(_daytimeActivities + _eveningActivities).any(
|
||||
(activity) => activity.ref == activityRef,
|
||||
),
|
||||
"Activity $activityRef not found",
|
||||
);
|
||||
_selectedActivities.remove(activityRef);
|
||||
@@ -135,12 +143,10 @@ class ActivitiesViewModel extends ChangeNotifier {
|
||||
|
||||
final itineraryConfig = resultConfig.value;
|
||||
final result = await _itineraryConfigRepository.setItineraryConfig(
|
||||
itineraryConfig.copyWith(activities: _selectedActivities.toList()));
|
||||
itineraryConfig.copyWith(activities: _selectedActivities.toList()),
|
||||
);
|
||||
if (result is Error) {
|
||||
_log.warning(
|
||||
'Failed to store ItineraryConfig',
|
||||
result.error,
|
||||
);
|
||||
_log.warning('Failed to store ItineraryConfig', result.error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -33,28 +33,24 @@ class ActivitiesList extends StatelessWidget {
|
||||
bottom: Dimens.paddingVertical,
|
||||
),
|
||||
sliver: SliverList(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
final activity = list[index];
|
||||
return Padding(
|
||||
padding:
|
||||
EdgeInsets.only(bottom: index < list.length - 1 ? 20 : 0),
|
||||
child: ActivityEntry(
|
||||
key: ValueKey(activity.ref),
|
||||
activity: activity,
|
||||
selected: viewModel.selectedActivities.contains(activity.ref),
|
||||
onChanged: (value) {
|
||||
if (value!) {
|
||||
viewModel.addActivity(activity.ref);
|
||||
} else {
|
||||
viewModel.removeActivity(activity.ref);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
childCount: list.length,
|
||||
),
|
||||
delegate: SliverChildBuilderDelegate((context, index) {
|
||||
final activity = list[index];
|
||||
return Padding(
|
||||
padding: EdgeInsets.only(bottom: index < list.length - 1 ? 20 : 0),
|
||||
child: ActivityEntry(
|
||||
key: ValueKey(activity.ref),
|
||||
activity: activity,
|
||||
selected: viewModel.selectedActivities.contains(activity.ref),
|
||||
onChanged: (value) {
|
||||
if (value!) {
|
||||
viewModel.addActivity(activity.ref);
|
||||
} else {
|
||||
viewModel.removeActivity(activity.ref);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}, childCount: list.length),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,10 +18,7 @@ import 'activity_time_of_day.dart';
|
||||
const String confirmButtonKey = 'confirm-button';
|
||||
|
||||
class ActivitiesScreen extends StatefulWidget {
|
||||
const ActivitiesScreen({
|
||||
super.key,
|
||||
required this.viewModel,
|
||||
});
|
||||
const ActivitiesScreen({super.key, required this.viewModel});
|
||||
|
||||
final ActivitiesViewModel viewModel;
|
||||
|
||||
@@ -68,13 +65,16 @@ class _ActivitiesScreenState extends State<ActivitiesScreen> {
|
||||
const ActivitiesHeader(),
|
||||
if (widget.viewModel.loadActivities.running)
|
||||
const Expanded(
|
||||
child: Center(child: CircularProgressIndicator())),
|
||||
child: Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
if (widget.viewModel.loadActivities.error)
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: ErrorIndicator(
|
||||
title: AppLocalization.of(context)
|
||||
.errorWhileLoadingActivities,
|
||||
title:
|
||||
AppLocalization.of(
|
||||
context,
|
||||
).errorWhileLoadingActivities,
|
||||
label: AppLocalization.of(context).tryAgain,
|
||||
onPressed: widget.viewModel.loadActivities.execute,
|
||||
),
|
||||
@@ -91,9 +91,7 @@ class _ActivitiesScreenState extends State<ActivitiesScreen> {
|
||||
Expanded(
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
const SliverToBoxAdapter(
|
||||
child: ActivitiesHeader(),
|
||||
),
|
||||
const SliverToBoxAdapter(child: ActivitiesHeader()),
|
||||
ActivitiesTitle(
|
||||
viewModel: widget.viewModel,
|
||||
activityTimeOfDay: ActivityTimeOfDay.daytime,
|
||||
@@ -145,9 +143,7 @@ class _ActivitiesScreenState extends State<ActivitiesScreen> {
|
||||
}
|
||||
|
||||
class _BottomArea extends StatelessWidget {
|
||||
const _BottomArea({
|
||||
required this.viewModel,
|
||||
});
|
||||
const _BottomArea({required this.viewModel});
|
||||
|
||||
final ActivitiesViewModel viewModel;
|
||||
|
||||
@@ -168,15 +164,17 @@ class _BottomArea extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
AppLocalization.of(context)
|
||||
.selected(viewModel.selectedActivities.length),
|
||||
AppLocalization.of(
|
||||
context,
|
||||
).selected(viewModel.selectedActivities.length),
|
||||
style: Theme.of(context).textTheme.labelLarge,
|
||||
),
|
||||
FilledButton(
|
||||
key: const Key(confirmButtonKey),
|
||||
onPressed: viewModel.selectedActivities.isNotEmpty
|
||||
? viewModel.saveActivities.execute
|
||||
: null,
|
||||
onPressed:
|
||||
viewModel.selectedActivities.isNotEmpty
|
||||
? viewModel.saveActivities.execute
|
||||
: null,
|
||||
child: Text(AppLocalization.of(context).confirm),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -37,7 +37,7 @@ class ActivitiesTitle extends StatelessWidget {
|
||||
}
|
||||
|
||||
String _label(BuildContext context) => switch (activityTimeOfDay) {
|
||||
ActivityTimeOfDay.daytime => AppLocalization.of(context).daytime,
|
||||
ActivityTimeOfDay.evening => AppLocalization.of(context).evening,
|
||||
};
|
||||
ActivityTimeOfDay.daytime => AppLocalization.of(context).daytime,
|
||||
ActivityTimeOfDay.evening => AppLocalization.of(context).evening,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class ActivityEntry extends StatelessWidget {
|
||||
key: ValueKey('${activity.ref}-checkbox'),
|
||||
value: selected,
|
||||
onChanged: onChanged,
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user