mirror of
https://github.com/flutter/samples.git
synced 2025-11-11 15:28:44 +00:00
128 lines
3.4 KiB
Dart
128 lines
3.4 KiB
Dart
// Copyright 2019 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/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:gallery/data/gallery_options.dart';
|
|
|
|
import 'package:gallery/studies/crane/model/formatters.dart';
|
|
|
|
import '../../../l10n/gallery_localizations.dart';
|
|
|
|
abstract class Destination {
|
|
const Destination({
|
|
@required this.id,
|
|
@required this.destination,
|
|
@required this.assetSemanticLabel,
|
|
}) : assert(id != null),
|
|
assert(destination != null);
|
|
|
|
final int id;
|
|
final String destination;
|
|
final String assetSemanticLabel;
|
|
|
|
String get assetName;
|
|
|
|
String subtitle(BuildContext context);
|
|
String subtitleSemantics(BuildContext context) => subtitle(context);
|
|
|
|
@override
|
|
String toString() => '$destination (id=$id)';
|
|
}
|
|
|
|
class FlyDestination extends Destination {
|
|
const FlyDestination({
|
|
@required int id,
|
|
@required String destination,
|
|
@required String assetSemanticLabel,
|
|
@required this.stops,
|
|
this.duration,
|
|
}) : assert(stops != null),
|
|
assert(destination != null),
|
|
super(
|
|
id: id,
|
|
destination: destination,
|
|
assetSemanticLabel: assetSemanticLabel,
|
|
);
|
|
|
|
final int stops;
|
|
final Duration duration;
|
|
|
|
String get assetName => 'assets/crane/destinations/fly_$id.jpg';
|
|
|
|
String subtitle(BuildContext context) {
|
|
final stopsText = GalleryLocalizations.of(context).craneFlyStops(stops);
|
|
|
|
if (duration == null) {
|
|
return stopsText;
|
|
} else {
|
|
final textDirection = GalleryOptions.of(context).textDirection();
|
|
final durationText =
|
|
formattedDuration(context, duration, abbreviated: true);
|
|
return textDirection == TextDirection.ltr
|
|
? '$stopsText · $durationText'
|
|
: '$durationText · $stopsText';
|
|
}
|
|
}
|
|
|
|
@override
|
|
String subtitleSemantics(BuildContext context) {
|
|
final stopsText = GalleryLocalizations.of(context).craneFlyStops(stops);
|
|
|
|
if (duration == null) {
|
|
return stopsText;
|
|
} else {
|
|
final durationText =
|
|
formattedDuration(context, duration, abbreviated: false);
|
|
return '$stopsText, $durationText';
|
|
}
|
|
}
|
|
}
|
|
|
|
class SleepDestination extends Destination {
|
|
const SleepDestination({
|
|
@required int id,
|
|
@required String destination,
|
|
@required String assetSemanticLabel,
|
|
@required this.total,
|
|
}) : assert(total != null),
|
|
assert(destination != null),
|
|
super(
|
|
id: id,
|
|
destination: destination,
|
|
assetSemanticLabel: assetSemanticLabel,
|
|
);
|
|
|
|
final int total;
|
|
|
|
String get assetName => 'assets/crane/destinations/sleep_$id.jpg';
|
|
|
|
String subtitle(BuildContext context) {
|
|
return GalleryLocalizations.of(context).craneSleepProperties(total);
|
|
}
|
|
}
|
|
|
|
class EatDestination extends Destination {
|
|
const EatDestination({
|
|
@required int id,
|
|
@required String destination,
|
|
@required String assetSemanticLabel,
|
|
@required this.total,
|
|
}) : assert(total != null),
|
|
assert(destination != null),
|
|
super(
|
|
id: id,
|
|
destination: destination,
|
|
assetSemanticLabel: assetSemanticLabel,
|
|
);
|
|
|
|
final int total;
|
|
|
|
String get assetName => 'assets/crane/destinations/eat_$id.jpg';
|
|
|
|
String subtitle(BuildContext context) {
|
|
return GalleryLocalizations.of(context).craneEatRestaurants(total);
|
|
}
|
|
}
|