mirror of
https://github.com/Myzel394/quid_faciam_hodie.git
synced 2025-06-20 08:05:26 +02:00
added memory map screen; improvements on memory sheet
This commit is contained in:
parent
8549d7c4a9
commit
4aff60a00c
@ -62,6 +62,20 @@
|
|||||||
"memorySheetUpdateMemoryMakePublic": "Veröffentlichen",
|
"memorySheetUpdateMemoryMakePublic": "Veröffentlichen",
|
||||||
"memorySheetUpdateMemoryMakePrivate": "Privat machen",
|
"memorySheetUpdateMemoryMakePrivate": "Privat machen",
|
||||||
"memorySheetDeleteMemory": "Erinnerung löschen",
|
"memorySheetDeleteMemory": "Erinnerung löschen",
|
||||||
|
"memorySheetViewMoreDetails": "Mehr Details",
|
||||||
|
|
||||||
|
|
||||||
|
"memoryMapScreenTitle": "Standort",
|
||||||
|
"memoryMapScreenExpandForMoreDescription": "Erweitere für mehr Details",
|
||||||
|
"memoryMapScreenOpenNavigation": "Navigation öffnen",
|
||||||
|
"memoryMapScreenValuesAddressLabel": "Geschätzte Adresse",
|
||||||
|
"memoryMapScreenValuesAddressIsLoading": "Adresse wird geladen...",
|
||||||
|
"memoryMapScreenValuesAddressIsUnavailable": "Address nicht verfügbar",
|
||||||
|
"memoryMapScreenValuesLatitudeLabel": "Latitude",
|
||||||
|
"memoryMapScreenValuesLongitudeLabel": "Longitude",
|
||||||
|
"memoryMapScreenValuesAltitudeLabel": "Höhe",
|
||||||
|
"memoryMapScreenValuesAccuracyLabel": "Genauigkeit",
|
||||||
|
"memoryMapScreenValuesSpeedLabel": "Geschwindigkeit",
|
||||||
|
|
||||||
|
|
||||||
"emptyScreenTitle": "Houston, wir haben ein Problem",
|
"emptyScreenTitle": "Houston, wir haben ein Problem",
|
||||||
|
@ -91,7 +91,44 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"memorySheetMapEstimatedAddressLabel": "Estimated Address",
|
"memorySheetMapEstimatedAddressLabel": "Estimated Address",
|
||||||
"memorySheetMapOpenNavigation": "Open Navigation",
|
"memorySheetViewMoreDetails": "View More Details",
|
||||||
|
|
||||||
|
|
||||||
|
"memoryMapScreenTitle": "Location",
|
||||||
|
"memoryMapScreenExpandForMoreDescription": "Expand for more details",
|
||||||
|
"memoryMapScreenOpenNavigation": "Open Navigation",
|
||||||
|
"memoryMapScreenValuesAddressLabel": "Estimated Address",
|
||||||
|
"memoryMapScreenValuesAddressIsLoading": "Loading address...",
|
||||||
|
"memoryMapScreenValuesAddressIsUnavailable": "Address not available",
|
||||||
|
"memoryMapScreenValuesLatitudeLabel": "Latitude",
|
||||||
|
"memoryMapScreenValuesLongitudeLabel": "Longitude",
|
||||||
|
"memoryMapScreenValuesAltitudeLabel": "Altitude",
|
||||||
|
"memoryMapScreenValuesAltitudeValue": "{valueInMeter}m",
|
||||||
|
"@memoryMapScreenValuesAltitudeValue": {
|
||||||
|
"placeholders": {
|
||||||
|
"valueInMeter": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"memoryMapScreenValuesAccuracyLabel": "Accuracy",
|
||||||
|
"memoryMapScreenValuesAccuracyValue": "{valueInMeter}m",
|
||||||
|
"@memoryMapScreenValuesAccuracyValue": {
|
||||||
|
"placeholders": {
|
||||||
|
"valueInMeter": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"memoryMapScreenValuesSpeedLabel": "Speed",
|
||||||
|
"memoryMapScreenValuesSpeedValue": "{valueInKmh} km/h",
|
||||||
|
"@memoryMapScreenValuesSpeedValue": {
|
||||||
|
"placeholders": {
|
||||||
|
"valueInKmh": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
"emptyScreenTitle": "Houston, we have a problem",
|
"emptyScreenTitle": "Houston, we have a problem",
|
||||||
|
204
lib/screens/memory_map_screen.dart
Normal file
204
lib/screens/memory_map_screen.dart
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
import 'package:expandable_bottom_sheet/expandable_bottom_sheet.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
|
import 'package:flutter_osm_plugin/flutter_osm_plugin.dart';
|
||||||
|
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||||
|
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
||||||
|
import 'package:quid_faciam_hodie/foreign_types/memory_location.dart';
|
||||||
|
import 'package:quid_faciam_hodie/utils/loadable.dart';
|
||||||
|
import 'package:quid_faciam_hodie/utils/lookup_address.dart';
|
||||||
|
import 'package:quid_faciam_hodie/utils/theme.dart';
|
||||||
|
import 'package:quid_faciam_hodie/widgets/icon_button_child.dart';
|
||||||
|
import 'package:quid_faciam_hodie/widgets/key_value_info.dart';
|
||||||
|
import 'package:quid_faciam_hodie/widgets/sheet_indicator.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
class MemoryMapScreen extends StatefulWidget {
|
||||||
|
final MemoryLocation location;
|
||||||
|
|
||||||
|
const MemoryMapScreen({
|
||||||
|
Key? key,
|
||||||
|
required this.location,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<MemoryMapScreen> createState() => _MemoryMapScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MemoryMapScreenState extends State<MemoryMapScreen> with Loadable {
|
||||||
|
late final MapController controller;
|
||||||
|
String? address;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
callWithLoading(fetchAddress);
|
||||||
|
|
||||||
|
controller = MapController(
|
||||||
|
initPosition: GeoPoint(
|
||||||
|
latitude: widget.location.latitude,
|
||||||
|
longitude: widget.location.longitude,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> fetchAddress() async {
|
||||||
|
try {
|
||||||
|
final foundAddress = await lookupAddress(
|
||||||
|
latitude: widget.location.latitude,
|
||||||
|
longitude: widget.location.longitude,
|
||||||
|
);
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
address = foundAddress;
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
setState(() {
|
||||||
|
address = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawCircle() => controller.drawCircle(
|
||||||
|
CircleOSM(
|
||||||
|
key: 'accuracy',
|
||||||
|
color: Colors.blue,
|
||||||
|
centerPoint: GeoPoint(
|
||||||
|
latitude: widget.location.latitude,
|
||||||
|
longitude: widget.location.longitude,
|
||||||
|
),
|
||||||
|
radius: widget.location.accuracy,
|
||||||
|
strokeWidth: 4,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
List<StaticPositionGeoPoint> get staticPoints => [
|
||||||
|
StaticPositionGeoPoint(
|
||||||
|
'position',
|
||||||
|
const MarkerIcon(
|
||||||
|
icon: Icon(Icons.location_on, size: 150, color: Colors.blue),
|
||||||
|
),
|
||||||
|
[
|
||||||
|
GeoPoint(
|
||||||
|
latitude: widget.location.latitude,
|
||||||
|
longitude: widget.location.longitude,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
];
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final localizations = AppLocalizations.of(context)!;
|
||||||
|
final backgroundColor = getSheetColor(context);
|
||||||
|
|
||||||
|
return PlatformScaffold(
|
||||||
|
appBar: PlatformAppBar(
|
||||||
|
title: Text(localizations.memoryMapScreenTitle),
|
||||||
|
),
|
||||||
|
body: ExpandableBottomSheet(
|
||||||
|
enableToggle: true,
|
||||||
|
background: OSMFlutter(
|
||||||
|
controller: controller,
|
||||||
|
initZoom: 13,
|
||||||
|
stepZoom: 1.0,
|
||||||
|
trackMyPosition: true,
|
||||||
|
staticPoints: staticPoints,
|
||||||
|
onMapIsReady: (_) {
|
||||||
|
drawCircle();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
persistentHeader: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
padding: const EdgeInsets.all(SMALL_SPACE),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: backgroundColor,
|
||||||
|
borderRadius: const BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(LARGE_SPACE),
|
||||||
|
topRight: Radius.circular(LARGE_SPACE),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(MEDIUM_SPACE),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
const SheetIndicator(),
|
||||||
|
const SizedBox(height: MEDIUM_SPACE),
|
||||||
|
Text(
|
||||||
|
localizations.memoryMapScreenExpandForMoreDescription,
|
||||||
|
style: getBodyTextTextStyle(context),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
expandableContent: Container(
|
||||||
|
color: backgroundColor,
|
||||||
|
padding: const EdgeInsets.all(MEDIUM_SPACE),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
KeyValueInfo(
|
||||||
|
title: localizations.memoryMapScreenValuesAddressLabel,
|
||||||
|
value: () {
|
||||||
|
if (isLoading) {
|
||||||
|
return localizations.memoryMapScreenValuesAddressIsLoading;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address == null) {
|
||||||
|
return localizations
|
||||||
|
.memoryMapScreenValuesAddressIsUnavailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
return address!;
|
||||||
|
}(),
|
||||||
|
),
|
||||||
|
const SizedBox(height: SMALL_SPACE),
|
||||||
|
PlatformTextButton(
|
||||||
|
onPressed: () {
|
||||||
|
final url =
|
||||||
|
'geo:0,0?q=${widget.location.latitude},${widget.location.longitude} (${address ?? ''})';
|
||||||
|
launchUrl(Uri.parse(url));
|
||||||
|
},
|
||||||
|
child: IconButtonChild(
|
||||||
|
icon: Icon(context.platformIcons.location),
|
||||||
|
label: Text(localizations.memoryMapScreenOpenNavigation),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
const SizedBox(height: SMALL_SPACE),
|
||||||
|
KeyValueInfo(
|
||||||
|
title: localizations.memoryMapScreenValuesLatitudeLabel,
|
||||||
|
value: widget.location.latitude.toString(),
|
||||||
|
),
|
||||||
|
KeyValueInfo(
|
||||||
|
title: localizations.memoryMapScreenValuesLongitudeLabel,
|
||||||
|
value: widget.location.longitude.toString(),
|
||||||
|
),
|
||||||
|
KeyValueInfo(
|
||||||
|
title: localizations.memoryMapScreenValuesAccuracyLabel,
|
||||||
|
value: localizations.memoryMapScreenValuesAccuracyValue(
|
||||||
|
widget.location.accuracy.toString(),
|
||||||
|
),
|
||||||
|
icon: Icons.circle,
|
||||||
|
),
|
||||||
|
KeyValueInfo(
|
||||||
|
title: localizations.memoryMapScreenValuesSpeedLabel,
|
||||||
|
value: localizations.memoryMapScreenValuesSpeedValue(
|
||||||
|
widget.location.speed.toString(),
|
||||||
|
),
|
||||||
|
icon: Icons.speed_rounded,
|
||||||
|
),
|
||||||
|
KeyValueInfo(
|
||||||
|
title: localizations.memoryMapScreenValuesAltitudeLabel,
|
||||||
|
value: localizations.memoryMapScreenValuesAltitudeValue(
|
||||||
|
widget.location.altitude.toString(),
|
||||||
|
),
|
||||||
|
icon: Icons.landscape_rounded,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -128,12 +128,7 @@ class _SettingsScreenState extends AuthRequiredState<SettingsScreen>
|
|||||||
Text(
|
Text(
|
||||||
localizations
|
localizations
|
||||||
.settingsScreenAccountSectionCreationDateLabel,
|
.settingsScreenAccountSectionCreationDateLabel,
|
||||||
style: platformThemeData(
|
style: getCaptionTextStyle(context),
|
||||||
context,
|
|
||||||
material: (data) => data.textTheme.bodySmall,
|
|
||||||
cupertino: (data) =>
|
|
||||||
data.textTheme.tabLabelTextStyle,
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -1,17 +1,12 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||||
import 'package:flutter_osm_plugin/flutter_osm_plugin.dart';
|
import 'package:flutter_osm_plugin/flutter_osm_plugin.dart';
|
||||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
import 'package:quid_faciam_hodie/constants/spacing.dart';
|
||||||
import 'package:quid_faciam_hodie/constants/values.dart';
|
import 'package:quid_faciam_hodie/constants/values.dart';
|
||||||
import 'package:quid_faciam_hodie/foreign_types/memory_location.dart';
|
import 'package:quid_faciam_hodie/foreign_types/memory_location.dart';
|
||||||
import 'package:quid_faciam_hodie/widgets/fade_and_move_in_animation.dart';
|
import 'package:quid_faciam_hodie/screens/memory_map_screen.dart';
|
||||||
import 'package:quid_faciam_hodie/widgets/icon_button_child.dart';
|
import 'package:quid_faciam_hodie/widgets/icon_button_child.dart';
|
||||||
import 'package:quid_faciam_hodie/widgets/key_value_info.dart';
|
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
|
||||||
|
|
||||||
class MemoryLocationView extends StatefulWidget {
|
class MemoryLocationView extends StatefulWidget {
|
||||||
final MemoryLocation location;
|
final MemoryLocation location;
|
||||||
@ -27,14 +22,11 @@ class MemoryLocationView extends StatefulWidget {
|
|||||||
|
|
||||||
class _MemoryLocationViewState extends State<MemoryLocationView> {
|
class _MemoryLocationViewState extends State<MemoryLocationView> {
|
||||||
late final MapController controller;
|
late final MapController controller;
|
||||||
String address = '';
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
lookupAddress();
|
|
||||||
|
|
||||||
controller = MapController(
|
controller = MapController(
|
||||||
initPosition: GeoPoint(
|
initPosition: GeoPoint(
|
||||||
latitude: widget.location.latitude,
|
latitude: widget.location.latitude,
|
||||||
@ -43,22 +35,11 @@ class _MemoryLocationViewState extends State<MemoryLocationView> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lookupAddress() async {
|
@override
|
||||||
final url =
|
void dispose() {
|
||||||
'https://geocode.maps.co/reverse?lat=${widget.location.latitude}&lon=${widget.location.longitude}';
|
controller.dispose();
|
||||||
final uri = Uri.parse(url);
|
|
||||||
|
|
||||||
final response = await http.get(uri);
|
super.dispose();
|
||||||
|
|
||||||
if (response.statusCode != 200) {
|
|
||||||
setState(() {
|
|
||||||
address = '';
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
setState(() {
|
|
||||||
address = jsonDecode(response.body)['display_name'];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawCircle() => controller.drawCircle(
|
void drawCircle() => controller.drawCircle(
|
||||||
@ -104,45 +85,45 @@ class _MemoryLocationViewState extends State<MemoryLocationView> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
height: 400,
|
height: 400,
|
||||||
|
child: GestureDetector(
|
||||||
|
// Avoid panning, map is view-only
|
||||||
|
onDoubleTap: () {},
|
||||||
child: OSMFlutter(
|
child: OSMFlutter(
|
||||||
controller: controller,
|
controller: controller,
|
||||||
initZoom: 14,
|
initZoom: 14,
|
||||||
stepZoom: 1.0,
|
minZoomLevel: 14,
|
||||||
|
maxZoomLevel: 14,
|
||||||
staticPoints: staticPoints,
|
staticPoints: staticPoints,
|
||||||
onMapIsReady: (_) {
|
onMapIsReady: (_) {
|
||||||
drawCircle();
|
drawCircle();
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: MEDIUM_SPACE),
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
const SizedBox(height: MEDIUM_SPACE),
|
|
||||||
if (address.isNotEmpty) ...[
|
|
||||||
FadeAndMoveInAnimation(
|
|
||||||
child: KeyValueInfo(
|
|
||||||
title: localizations.memorySheetMapEstimatedAddressLabel,
|
|
||||||
value: address,
|
|
||||||
icon: context.platformIcons.location,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: MEDIUM_SPACE),
|
const SizedBox(height: MEDIUM_SPACE),
|
||||||
],
|
|
||||||
PlatformTextButton(
|
PlatformTextButton(
|
||||||
onPressed: () {
|
|
||||||
final url =
|
|
||||||
'geo:0,0?q=${widget.location.latitude},${widget.location.longitude} ($address)';
|
|
||||||
launchUrl(Uri.parse(url));
|
|
||||||
},
|
|
||||||
child: IconButtonChild(
|
child: IconButtonChild(
|
||||||
icon: Icon(context.platformIcons.location),
|
icon: Icon(context.platformIcons.fullscreen),
|
||||||
label: Text(localizations.memorySheetMapOpenNavigation),
|
label: Text(localizations.memorySheetViewMoreDetails),
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
await Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (_) => MemoryMapScreen(
|
||||||
|
location: widget.location,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
);
|
||||||
),
|
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Navigator.pop(context);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: MEDIUM_SPACE),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -129,12 +129,7 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final localizations = AppLocalizations.of(context)!;
|
final localizations = AppLocalizations.of(context)!;
|
||||||
final backgroundColor = platformThemeData(
|
final backgroundColor = getSheetColor(context);
|
||||||
context,
|
|
||||||
material: (data) =>
|
|
||||||
data.bottomSheetTheme.modalBackgroundColor ?? data.bottomAppBarColor,
|
|
||||||
cupertino: (data) => data.barBackgroundColor,
|
|
||||||
);
|
|
||||||
|
|
||||||
return ExpandableBottomSheet(
|
return ExpandableBottomSheet(
|
||||||
background: GestureDetector(
|
background: GestureDetector(
|
||||||
@ -151,13 +146,13 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
|
|||||||
),
|
),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
if (widget.memory.location != null) ...[
|
||||||
const Padding(
|
const Padding(
|
||||||
padding: EdgeInsets.symmetric(
|
padding: EdgeInsets.all(SMALL_SPACE),
|
||||||
vertical: MEDIUM_SPACE,
|
|
||||||
horizontal: MEDIUM_SPACE,
|
|
||||||
),
|
|
||||||
child: SheetIndicator(),
|
child: SheetIndicator(),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: MEDIUM_SPACE),
|
||||||
|
],
|
||||||
Text(
|
Text(
|
||||||
localizations.memorySheetTitle,
|
localizations.memorySheetTitle,
|
||||||
style: getTitleTextStyle(context),
|
style: getTitleTextStyle(context),
|
||||||
@ -224,23 +219,19 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
|
|||||||
? buildLoadingIndicator()
|
? buildLoadingIndicator()
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
],
|
const SizedBox(height: MEDIUM_SPACE),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
context.platformIcons.time,
|
||||||
|
size: platformThemeData(
|
||||||
|
context,
|
||||||
|
material: (data) => data.textTheme.bodyLarge!.fontSize,
|
||||||
|
cupertino: (data) => data.textTheme.textStyle.fontSize,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
expandableContent: Container(
|
const SizedBox(width: TINY_SPACE),
|
||||||
width: double.infinity,
|
|
||||||
color: backgroundColor,
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
widget.memory.location == null
|
|
||||||
? const SizedBox.shrink()
|
|
||||||
: MemoryLocationView(
|
|
||||||
location: widget.memory.location!,
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(MEDIUM_SPACE),
|
|
||||||
child: Column(
|
|
||||||
children: <Widget>[
|
|
||||||
Text(
|
Text(
|
||||||
localizations.memorySheetCreatedAtDataKey(
|
localizations.memorySheetCreatedAtDataKey(
|
||||||
DateFormat.jms().format(
|
DateFormat.jms().format(
|
||||||
@ -249,16 +240,18 @@ class _MemorySheetState extends State<MemorySheet> with Loadable {
|
|||||||
),
|
),
|
||||||
style: getBodyTextTextStyle(context),
|
style: getBodyTextTextStyle(context),
|
||||||
),
|
),
|
||||||
const SizedBox(height: SMALL_SPACE),
|
],
|
||||||
Text(
|
|
||||||
widget.memory.id,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: getBodyTextTextStyle(context),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
expandableContent: widget.memory.location == null
|
||||||
|
? const SizedBox.shrink()
|
||||||
|
: Container(
|
||||||
|
width: double.infinity,
|
||||||
|
color: backgroundColor,
|
||||||
|
child: MemoryLocationView(
|
||||||
|
location: widget.memory.location!,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
15
lib/utils/lookup_address.dart
Normal file
15
lib/utils/lookup_address.dart
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
|
Future<String> lookupAddress({
|
||||||
|
required final double latitude,
|
||||||
|
required final double longitude,
|
||||||
|
}) async {
|
||||||
|
final url = 'https://geocode.maps.co/reverse?lat=$latitude&lon=$longitude';
|
||||||
|
final uri = Uri.parse(url);
|
||||||
|
|
||||||
|
final response = await http.get(uri);
|
||||||
|
|
||||||
|
return jsonDecode(response.body)['display_name'];
|
||||||
|
}
|
@ -24,3 +24,16 @@ TextStyle getSubTitleTextStyle(final BuildContext context) => platformThemeData(
|
|||||||
material: (data) => data.textTheme.subtitle1!,
|
material: (data) => data.textTheme.subtitle1!,
|
||||||
cupertino: (data) => data.textTheme.navTitleTextStyle,
|
cupertino: (data) => data.textTheme.navTitleTextStyle,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TextStyle getCaptionTextStyle(final BuildContext context) => platformThemeData(
|
||||||
|
context,
|
||||||
|
material: (data) => data.textTheme.caption!,
|
||||||
|
cupertino: (data) => data.textTheme.tabLabelTextStyle,
|
||||||
|
);
|
||||||
|
|
||||||
|
Color getSheetColor(final BuildContext context) => platformThemeData(
|
||||||
|
context,
|
||||||
|
material: (data) =>
|
||||||
|
data.bottomSheetTheme.modalBackgroundColor ?? data.bottomAppBarColor,
|
||||||
|
cupertino: (data) => data.barBackgroundColor,
|
||||||
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user