fix(mobile): map markers not loading with int coordinates (#3957)
* fix(mobile): increase zoom-level for map zoom to asset * refactor(mobile): map-view - rename lastAssetOffsetInSheet * Workaround OpenAPI Dart generator bug * fix(mobile): map - increase appbar top padding * fix(mobile): navigation bar overlapping map bottom sheet * fix(mobile): map - do not animate the drag handle of bottom sheet on scroll * fix(mobile): F-Droid build failure due to map view * fix(mobile): remove jank on map asset marker update * fix(mobile): map view app-bar padding is made dynamic * fix(mobile): reduce debounce time in bottom sheet asset scroll * fix(mobile): bottom sheet - reduce drag handle total height --------- Co-authored-by: Daniele Ricci <daniele@casaricci.it>
This commit is contained in:
parent
816d040d81
commit
f8d26bd865
10 changed files with 178 additions and 120 deletions
|
@ -96,3 +96,8 @@ dependencies {
|
||||||
implementation "com.github.bumptech.glide:glide:$glide_version"
|
implementation "com.github.bumptech.glide:glide:$glide_version"
|
||||||
kapt "com.github.bumptech.glide:compiler:$glide_version"
|
kapt "com.github.bumptech.glide:compiler:$glide_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is uncommented in F-Droid build script
|
||||||
|
//f configurations.all {
|
||||||
|
//f exclude group: 'com.google.android.gms'
|
||||||
|
//f }
|
||||||
|
|
|
@ -55,7 +55,6 @@
|
||||||
|
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32"/>
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
|
||||||
|
|
|
@ -5,10 +5,10 @@ import 'package:immich_mobile/utils/image_url_builder.dart';
|
||||||
|
|
||||||
class AssetMarkerIcon extends StatelessWidget {
|
class AssetMarkerIcon extends StatelessWidget {
|
||||||
const AssetMarkerIcon({
|
const AssetMarkerIcon({
|
||||||
Key? key,
|
super.key,
|
||||||
required this.id,
|
required this.id,
|
||||||
this.isDarkTheme = false,
|
this.isDarkTheme = false,
|
||||||
}) : super(key: key);
|
});
|
||||||
|
|
||||||
final String id;
|
final String id;
|
||||||
final bool isDarkTheme;
|
final bool isDarkTheme;
|
||||||
|
|
|
@ -122,7 +122,7 @@ class MapAppBar extends HookWidget implements PreferredSizeWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(top: 30),
|
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 15),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
@ -41,7 +42,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
|
||||||
// Non-State variables
|
// Non-State variables
|
||||||
bool userTappedOnMap = false;
|
bool userTappedOnMap = false;
|
||||||
RenderList? _cachedRenderList;
|
RenderList? _cachedRenderList;
|
||||||
int lastAssetOffsetInSheet = -1;
|
int assetOffsetInSheet = -1;
|
||||||
late final DraggableScrollableController bottomSheetController;
|
late final DraggableScrollableController bottomSheetController;
|
||||||
late final Debounce debounce;
|
late final Debounce debounce;
|
||||||
|
|
||||||
|
@ -50,14 +51,16 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
|
||||||
super.initState();
|
super.initState();
|
||||||
bottomSheetController = DraggableScrollableController();
|
bottomSheetController = DraggableScrollableController();
|
||||||
debounce = Debounce(
|
debounce = Debounce(
|
||||||
const Duration(milliseconds: 200),
|
const Duration(milliseconds: 100),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
|
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
|
||||||
double maxHeight = MediaQuery.of(context).size.height;
|
final bottomPadding =
|
||||||
|
Platform.isAndroid ? MediaQuery.of(context).padding.bottom - 10 : 0.0;
|
||||||
|
final maxHeight = MediaQuery.of(context).size.height - bottomPadding;
|
||||||
final isSheetScrolled = useState(false);
|
final isSheetScrolled = useState(false);
|
||||||
final isSheetExpanded = useState(false);
|
final isSheetExpanded = useState(false);
|
||||||
final assetsInBound = useState(<Asset>[]);
|
final assetsInBound = useState(<Asset>[]);
|
||||||
|
@ -68,7 +71,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
|
||||||
assetsInBound.value = event.assets;
|
assetsInBound.value = event.assets;
|
||||||
} else if (event is MapPageOnTapEvent) {
|
} else if (event is MapPageOnTapEvent) {
|
||||||
userTappedOnMap = true;
|
userTappedOnMap = true;
|
||||||
lastAssetOffsetInSheet = -1;
|
assetOffsetInSheet = -1;
|
||||||
bottomSheetController.animateTo(
|
bottomSheetController.animateTo(
|
||||||
0.1,
|
0.1,
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(milliseconds: 200),
|
||||||
|
@ -98,8 +101,8 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
|
||||||
columnOffset = columnOffset < renderElement.totalCount
|
columnOffset = columnOffset < renderElement.totalCount
|
||||||
? columnOffset
|
? columnOffset
|
||||||
: renderElement.totalCount - 1;
|
: renderElement.totalCount - 1;
|
||||||
lastAssetOffsetInSheet = rowOffset + columnOffset;
|
assetOffsetInSheet = rowOffset + columnOffset;
|
||||||
final asset = _cachedRenderList?.allAssets?[lastAssetOffsetInSheet];
|
final asset = _cachedRenderList?.allAssets?[assetOffsetInSheet];
|
||||||
userTappedOnMap = false;
|
userTappedOnMap = false;
|
||||||
if (!userTappedOnMap && isSheetExpanded.value) {
|
if (!userTappedOnMap && isSheetExpanded.value) {
|
||||||
widget.bottomSheetEventSC.add(
|
widget.bottomSheetEventSC.add(
|
||||||
|
@ -162,10 +165,10 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void onTapMapButton() {
|
void onTapMapButton() {
|
||||||
if (lastAssetOffsetInSheet != -1) {
|
if (assetOffsetInSheet != -1) {
|
||||||
widget.bottomSheetEventSC.add(
|
widget.bottomSheetEventSC.add(
|
||||||
MapPageZoomToAsset(
|
MapPageZoomToAsset(
|
||||||
_cachedRenderList?.allAssets?[lastAssetOffsetInSheet],
|
_cachedRenderList?.allAssets?[assetOffsetInSheet],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -176,7 +179,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
|
||||||
? "${assetsInBound.value.length} photo${assetsInBound.value.length > 1 ? "s" : ""}"
|
? "${assetsInBound.value.length} photo${assetsInBound.value.length > 1 ? "s" : ""}"
|
||||||
: "map_no_assets_in_bounds".tr();
|
: "map_no_assets_in_bounds".tr();
|
||||||
final dragHandle = Container(
|
final dragHandle = Container(
|
||||||
height: 75,
|
height: 60,
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
|
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
|
||||||
|
@ -187,9 +190,9 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 5),
|
||||||
const CustomDraggingHandle(),
|
const CustomDraggingHandle(),
|
||||||
const SizedBox(height: 12),
|
const SizedBox(height: 15),
|
||||||
Text(
|
Text(
|
||||||
textToDisplay,
|
textToDisplay,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
|
@ -199,6 +202,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Divider(
|
Divider(
|
||||||
|
height: 10,
|
||||||
color: Theme.of(context)
|
color: Theme.of(context)
|
||||||
.textTheme
|
.textTheme
|
||||||
.displayLarge
|
.displayLarge
|
||||||
|
@ -226,6 +230,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
|
||||||
);
|
);
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
controller: scrollController,
|
controller: scrollController,
|
||||||
|
physics: const ClampingScrollPhysics(),
|
||||||
child: dragHandle,
|
child: dragHandle,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -238,118 +243,125 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
|
||||||
if (!sheetExtended) {
|
if (!sheetExtended) {
|
||||||
// reset state
|
// reset state
|
||||||
userTappedOnMap = false;
|
userTappedOnMap = false;
|
||||||
lastAssetOffsetInSheet = -1;
|
assetOffsetInSheet = -1;
|
||||||
isSheetScrolled.value = false;
|
isSheetScrolled.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
child: Stack(
|
child: Padding(
|
||||||
children: [
|
padding: EdgeInsets.only(
|
||||||
DraggableScrollableSheet(
|
bottom: bottomPadding,
|
||||||
controller: bottomSheetController,
|
),
|
||||||
initialChildSize: 0.1,
|
child: Stack(
|
||||||
minChildSize: 0.1,
|
children: [
|
||||||
maxChildSize: 0.55,
|
DraggableScrollableSheet(
|
||||||
snap: true,
|
controller: bottomSheetController,
|
||||||
builder: (
|
initialChildSize: 0.1,
|
||||||
BuildContext context,
|
minChildSize: 0.1,
|
||||||
ScrollController scrollController,
|
maxChildSize: 0.55,
|
||||||
) {
|
snap: true,
|
||||||
return Card(
|
builder: (
|
||||||
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
|
BuildContext context,
|
||||||
surfaceTintColor: Colors.transparent,
|
ScrollController scrollController,
|
||||||
elevation: 18.0,
|
) {
|
||||||
margin: const EdgeInsets.all(0),
|
return Card(
|
||||||
child: Column(
|
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
|
||||||
children: [
|
surfaceTintColor: Colors.transparent,
|
||||||
buildDragHandle(scrollController),
|
elevation: 18.0,
|
||||||
if (isSheetExpanded.value && assetsInBound.value.isNotEmpty)
|
margin: const EdgeInsets.all(0),
|
||||||
ref
|
child: Column(
|
||||||
.watch(
|
children: [
|
||||||
renderListProvider(
|
buildDragHandle(scrollController),
|
||||||
assetsInBound.value,
|
if (isSheetExpanded.value &&
|
||||||
),
|
assetsInBound.value.isNotEmpty)
|
||||||
)
|
ref
|
||||||
.when(
|
.watch(
|
||||||
data: (renderList) {
|
renderListProvider(
|
||||||
_cachedRenderList = renderList;
|
assetsInBound.value,
|
||||||
final assetGrid = ImmichAssetGrid(
|
),
|
||||||
shrinkWrap: true,
|
)
|
||||||
renderList: renderList,
|
.when(
|
||||||
showDragScroll: false,
|
data: (renderList) {
|
||||||
selectionActive: widget.selectionEnabled,
|
_cachedRenderList = renderList;
|
||||||
showMultiSelectIndicator: false,
|
final assetGrid = ImmichAssetGrid(
|
||||||
listener: widget.selectionlistener,
|
shrinkWrap: true,
|
||||||
visibleItemsListener: visibleItemsListener,
|
renderList: renderList,
|
||||||
);
|
showDragScroll: false,
|
||||||
|
selectionActive: widget.selectionEnabled,
|
||||||
|
showMultiSelectIndicator: false,
|
||||||
|
listener: widget.selectionlistener,
|
||||||
|
visibleItemsListener: visibleItemsListener,
|
||||||
|
);
|
||||||
|
|
||||||
return Expanded(child: assetGrid);
|
return Expanded(child: assetGrid);
|
||||||
},
|
},
|
||||||
error: (error, stackTrace) {
|
error: (error, stackTrace) {
|
||||||
log.warning(
|
log.warning(
|
||||||
"Cannot get assets in the current map bounds ${error.toString()}",
|
"Cannot get assets in the current map bounds ${error.toString()}",
|
||||||
error,
|
error,
|
||||||
stackTrace,
|
stackTrace,
|
||||||
);
|
);
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
},
|
},
|
||||||
loading: () => const SizedBox.shrink(),
|
loading: () => const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
if (isSheetExpanded.value && assetsInBound.value.isEmpty)
|
||||||
|
Expanded(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: buildNoPhotosWidget(),
|
||||||
),
|
),
|
||||||
if (isSheetExpanded.value && assetsInBound.value.isEmpty)
|
|
||||||
Expanded(
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: buildNoPhotosWidget(),
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: maxHeight * currentExtend.value,
|
||||||
|
left: 0,
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: () => launchUrl(
|
||||||
|
Uri.parse('https://openstreetmap.org/copyright'),
|
||||||
),
|
),
|
||||||
);
|
child: ColoredBox(
|
||||||
},
|
color: (widget.isDarkTheme
|
||||||
),
|
? Colors.grey[900]
|
||||||
Positioned(
|
: Colors.grey[100])!,
|
||||||
bottom: maxHeight * currentExtend.value,
|
child: Padding(
|
||||||
left: 0,
|
padding: const EdgeInsets.all(3),
|
||||||
child: GestureDetector(
|
child: Text(
|
||||||
onTap: () => launchUrl(
|
'© OpenStreetMap contributors',
|
||||||
Uri.parse('https://openstreetmap.org/copyright'),
|
style: TextStyle(
|
||||||
),
|
fontSize: 6,
|
||||||
child: ColoredBox(
|
color: !widget.isDarkTheme
|
||||||
color:
|
? Colors.grey[900]
|
||||||
(widget.isDarkTheme ? Colors.grey[900] : Colors.grey[100])!,
|
: Colors.grey[100],
|
||||||
child: Padding(
|
),
|
||||||
padding: const EdgeInsets.all(3),
|
|
||||||
child: Text(
|
|
||||||
'© OpenStreetMap contributors',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 6,
|
|
||||||
color: !widget.isDarkTheme
|
|
||||||
? Colors.grey[900]
|
|
||||||
: Colors.grey[100],
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
Positioned(
|
||||||
Positioned(
|
bottom: maxHeight * (0.14 + (currentExtend.value - 0.1)),
|
||||||
bottom: maxHeight * (0.14 + (currentExtend.value - 0.1)),
|
right: 15,
|
||||||
right: 15,
|
child: ElevatedButton(
|
||||||
child: ElevatedButton(
|
onPressed: () => widget.bottomSheetEventSC
|
||||||
onPressed: () =>
|
.add(const MapPageZoomToLocation()),
|
||||||
widget.bottomSheetEventSC.add(const MapPageZoomToLocation()),
|
style: ElevatedButton.styleFrom(
|
||||||
style: ElevatedButton.styleFrom(
|
shape: const CircleBorder(),
|
||||||
shape: const CircleBorder(),
|
padding: const EdgeInsets.all(12),
|
||||||
padding: const EdgeInsets.all(12),
|
),
|
||||||
),
|
child: const Icon(
|
||||||
child: const Icon(
|
Icons.my_location,
|
||||||
Icons.my_location,
|
size: 22,
|
||||||
size: 22,
|
fill: 1,
|
||||||
fill: 1,
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,14 +166,15 @@ class MapPageState extends ConsumerState<MapPage> {
|
||||||
final mapMarker = mapMarkerData.value
|
final mapMarker = mapMarkerData.value
|
||||||
.firstWhereOrNull((e) => e.asset.id == assetInBottomSheet.id);
|
.firstWhereOrNull((e) => e.asset.id == assetInBottomSheet.id);
|
||||||
if (mapMarker != null) {
|
if (mapMarker != null) {
|
||||||
|
const zoomLevel = 16.0;
|
||||||
LatLng? newCenter = mapController.centerBoundsWithPadding(
|
LatLng? newCenter = mapController.centerBoundsWithPadding(
|
||||||
mapMarker.point,
|
mapMarker.point,
|
||||||
const Offset(0, -120),
|
const Offset(0, -120),
|
||||||
zoomLevel: 6,
|
zoomLevel: zoomLevel,
|
||||||
);
|
);
|
||||||
if (newCenter != null) {
|
if (newCenter != null) {
|
||||||
forceAssetUpdate = true;
|
forceAssetUpdate = true;
|
||||||
mapController.move(newCenter, 6);
|
mapController.move(newCenter, zoomLevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -385,6 +386,7 @@ class MapPageState extends ConsumerState<MapPage> {
|
||||||
builder: (ctx) => GestureDetector(
|
builder: (ctx) => GestureDetector(
|
||||||
onTap: () => openAssetInViewer(closestAssetMarker.value!.asset),
|
onTap: () => openAssetInViewer(closestAssetMarker.value!.asset),
|
||||||
child: AssetMarkerIcon(
|
child: AssetMarkerIcon(
|
||||||
|
key: Key(closestAssetMarker.value!.asset.remoteId!),
|
||||||
isDarkTheme: isDarkTheme,
|
isDarkTheme: isDarkTheme,
|
||||||
id: closestAssetMarker.value!.asset.remoteId!,
|
id: closestAssetMarker.value!.asset.remoteId!,
|
||||||
),
|
),
|
||||||
|
@ -421,8 +423,15 @@ class MapPageState extends ConsumerState<MapPage> {
|
||||||
|
|
||||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||||
value: SystemUiOverlayStyle(
|
value: SystemUiOverlayStyle(
|
||||||
statusBarColor: Colors.black.withOpacity(0.5),
|
statusBarColor:
|
||||||
statusBarIconBrightness: Brightness.light,
|
(isDarkTheme ? Colors.black : Colors.white).withOpacity(0.5),
|
||||||
|
statusBarIconBrightness:
|
||||||
|
isDarkTheme ? Brightness.light : Brightness.dark,
|
||||||
|
systemNavigationBarColor:
|
||||||
|
isDarkTheme ? Colors.grey[900] : Colors.grey[100],
|
||||||
|
systemNavigationBarIconBrightness:
|
||||||
|
isDarkTheme ? Brightness.light : Brightness.dark,
|
||||||
|
systemNavigationBarDividerColor: Colors.transparent,
|
||||||
),
|
),
|
||||||
child: Theme(
|
child: Theme(
|
||||||
// Override app theme based on map theme
|
// Override app theme based on map theme
|
||||||
|
|
|
@ -57,8 +57,8 @@ class MapMarkerResponseDto {
|
||||||
|
|
||||||
return MapMarkerResponseDto(
|
return MapMarkerResponseDto(
|
||||||
id: mapValueOfType<String>(json, r'id')!,
|
id: mapValueOfType<String>(json, r'id')!,
|
||||||
lat: mapValueOfType<double>(json, r'lat')!,
|
lat: (mapValueOfType<num>(json, r'lat')!).toDouble(),
|
||||||
lon: mapValueOfType<double>(json, r'lon')!,
|
lon: (mapValueOfType<num>(json, r'lon')!).toDouble(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -60,6 +60,15 @@ dependencies:
|
||||||
image_picker: ^0.8.5+3 # only used to select user profile image from system gallery -> we can simply select an image from within immich?
|
image_picker: ^0.8.5+3 # only used to select user profile image from system gallery -> we can simply select an image from within immich?
|
||||||
logging: ^1.1.0
|
logging: ^1.1.0
|
||||||
|
|
||||||
|
# This is uncommented in F-Droid build script
|
||||||
|
# Taken from https://github.com/Myzel394/locus/blob/445013d22ec1d759027d4303bd65b30c5c8588c8/pubspec.yaml#L105
|
||||||
|
#fdependency_overrides:
|
||||||
|
#f geolocator_android:
|
||||||
|
#f git:
|
||||||
|
#f url: https://github.com/Zverik/flutter-geolocator.git
|
||||||
|
#f ref: floss
|
||||||
|
#f path: geolocator_android
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
|
@ -204,6 +204,10 @@ class {{{classname}}} {
|
||||||
? {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}
|
? {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}
|
||||||
: {{{datatypeWithEnum}}}.parse(json[r'{{{baseName}}}'].toString()),
|
: {{{datatypeWithEnum}}}.parse(json[r'{{{baseName}}}'].toString()),
|
||||||
{{/isNumber}}
|
{{/isNumber}}
|
||||||
|
{{#isDouble}}
|
||||||
|
{{{name}}}: (mapValueOfType<num>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}}).toDouble(),
|
||||||
|
{{/isDouble}}
|
||||||
|
{{^isDouble}}
|
||||||
{{^isNumber}}
|
{{^isNumber}}
|
||||||
{{^isEnum}}
|
{{^isEnum}}
|
||||||
{{{name}}}: mapValueOfType<{{{datatypeWithEnum}}}>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
{{{name}}}: mapValueOfType<{{{datatypeWithEnum}}}>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||||
|
@ -212,6 +216,7 @@ class {{{classname}}} {
|
||||||
{{{name}}}: {{{enumName}}}.fromJson(json[r'{{{baseName}}}']){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
{{{name}}}: {{{enumName}}}.fromJson(json[r'{{{baseName}}}']){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||||
{{/isEnum}}
|
{{/isEnum}}
|
||||||
{{/isNumber}}
|
{{/isNumber}}
|
||||||
|
{{/isDouble}}
|
||||||
{{/isMap}}
|
{{/isMap}}
|
||||||
{{/isArray}}
|
{{/isArray}}
|
||||||
{{/complexType}}
|
{{/complexType}}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--- native_class.mustache 2023-06-22 12:56:11.090350406 -0500
|
--- native_class.mustache 2023-08-31 23:09:59.584269162 +0200
|
||||||
+++ native_class1.mustache 2023-06-22 12:57:14.498184792 -0500
|
+++ native_class1.mustache 2023-08-31 22:59:53.633083270 +0200
|
||||||
@@ -91,14 +91,14 @@
|
@@ -91,14 +91,14 @@
|
||||||
{{/isDateTime}}
|
{{/isDateTime}}
|
||||||
{{#isNullable}}
|
{{#isNullable}}
|
||||||
|
@ -35,3 +35,22 @@
|
||||||
return {{{classname}}}(
|
return {{{classname}}}(
|
||||||
{{#vars}}
|
{{#vars}}
|
||||||
{{#isDateTime}}
|
{{#isDateTime}}
|
||||||
|
@@ -215,6 +204,10 @@
|
||||||
|
? {{#defaultValue}}{{{.}}}{{/defaultValue}}{{^defaultValue}}null{{/defaultValue}}
|
||||||
|
: {{{datatypeWithEnum}}}.parse(json[r'{{{baseName}}}'].toString()),
|
||||||
|
{{/isNumber}}
|
||||||
|
+ {{#isDouble}}
|
||||||
|
+ {{{name}}}: (mapValueOfType<num>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}}).toDouble(),
|
||||||
|
+ {{/isDouble}}
|
||||||
|
+ {{^isDouble}}
|
||||||
|
{{^isNumber}}
|
||||||
|
{{^isEnum}}
|
||||||
|
{{{name}}}: mapValueOfType<{{{datatypeWithEnum}}}>(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||||
|
@@ -223,6 +216,7 @@
|
||||||
|
{{{name}}}: {{{enumName}}}.fromJson(json[r'{{{baseName}}}']){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}},
|
||||||
|
{{/isEnum}}
|
||||||
|
{{/isNumber}}
|
||||||
|
+ {{/isDouble}}
|
||||||
|
{{/isMap}}
|
||||||
|
{{/isArray}}
|
||||||
|
{{/complexType}}
|
||||||
|
|
Loading…
Reference in a new issue