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:
shenlong 2023-09-04 23:08:43 +00:00 committed by GitHub
parent 816d040d81
commit f8d26bd865
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 178 additions and 120 deletions

View file

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
@ -41,7 +42,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
// Non-State variables
bool userTappedOnMap = false;
RenderList? _cachedRenderList;
int lastAssetOffsetInSheet = -1;
int assetOffsetInSheet = -1;
late final DraggableScrollableController bottomSheetController;
late final Debounce debounce;
@ -50,14 +51,16 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
super.initState();
bottomSheetController = DraggableScrollableController();
debounce = Debounce(
const Duration(milliseconds: 200),
const Duration(milliseconds: 100),
);
}
@override
Widget build(BuildContext context) {
var isDarkMode = Theme.of(context).brightness == Brightness.dark;
double maxHeight = MediaQuery.of(context).size.height;
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
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 isSheetExpanded = useState(false);
final assetsInBound = useState(<Asset>[]);
@ -68,7 +71,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
assetsInBound.value = event.assets;
} else if (event is MapPageOnTapEvent) {
userTappedOnMap = true;
lastAssetOffsetInSheet = -1;
assetOffsetInSheet = -1;
bottomSheetController.animateTo(
0.1,
duration: const Duration(milliseconds: 200),
@ -98,8 +101,8 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
columnOffset = columnOffset < renderElement.totalCount
? columnOffset
: renderElement.totalCount - 1;
lastAssetOffsetInSheet = rowOffset + columnOffset;
final asset = _cachedRenderList?.allAssets?[lastAssetOffsetInSheet];
assetOffsetInSheet = rowOffset + columnOffset;
final asset = _cachedRenderList?.allAssets?[assetOffsetInSheet];
userTappedOnMap = false;
if (!userTappedOnMap && isSheetExpanded.value) {
widget.bottomSheetEventSC.add(
@ -162,10 +165,10 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
}
void onTapMapButton() {
if (lastAssetOffsetInSheet != -1) {
if (assetOffsetInSheet != -1) {
widget.bottomSheetEventSC.add(
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" : ""}"
: "map_no_assets_in_bounds".tr();
final dragHandle = Container(
height: 75,
height: 60,
width: double.infinity,
decoration: BoxDecoration(
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
@ -187,9 +190,9 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(height: 12),
const SizedBox(height: 5),
const CustomDraggingHandle(),
const SizedBox(height: 12),
const SizedBox(height: 15),
Text(
textToDisplay,
style: TextStyle(
@ -199,6 +202,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
),
),
Divider(
height: 10,
color: Theme.of(context)
.textTheme
.displayLarge
@ -226,6 +230,7 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
);
return SingleChildScrollView(
controller: scrollController,
physics: const ClampingScrollPhysics(),
child: dragHandle,
);
}
@ -238,118 +243,125 @@ class AssetsInBoundBottomSheetState extends ConsumerState<MapPageBottomSheet> {
if (!sheetExtended) {
// reset state
userTappedOnMap = false;
lastAssetOffsetInSheet = -1;
assetOffsetInSheet = -1;
isSheetScrolled.value = false;
}
return true;
},
child: Stack(
children: [
DraggableScrollableSheet(
controller: bottomSheetController,
initialChildSize: 0.1,
minChildSize: 0.1,
maxChildSize: 0.55,
snap: true,
builder: (
BuildContext context,
ScrollController scrollController,
) {
return Card(
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
surfaceTintColor: Colors.transparent,
elevation: 18.0,
margin: const EdgeInsets.all(0),
child: Column(
children: [
buildDragHandle(scrollController),
if (isSheetExpanded.value && assetsInBound.value.isNotEmpty)
ref
.watch(
renderListProvider(
assetsInBound.value,
),
)
.when(
data: (renderList) {
_cachedRenderList = renderList;
final assetGrid = ImmichAssetGrid(
shrinkWrap: true,
renderList: renderList,
showDragScroll: false,
selectionActive: widget.selectionEnabled,
showMultiSelectIndicator: false,
listener: widget.selectionlistener,
visibleItemsListener: visibleItemsListener,
);
child: Padding(
padding: EdgeInsets.only(
bottom: bottomPadding,
),
child: Stack(
children: [
DraggableScrollableSheet(
controller: bottomSheetController,
initialChildSize: 0.1,
minChildSize: 0.1,
maxChildSize: 0.55,
snap: true,
builder: (
BuildContext context,
ScrollController scrollController,
) {
return Card(
color: isDarkMode ? Colors.grey[900] : Colors.grey[100],
surfaceTintColor: Colors.transparent,
elevation: 18.0,
margin: const EdgeInsets.all(0),
child: Column(
children: [
buildDragHandle(scrollController),
if (isSheetExpanded.value &&
assetsInBound.value.isNotEmpty)
ref
.watch(
renderListProvider(
assetsInBound.value,
),
)
.when(
data: (renderList) {
_cachedRenderList = renderList;
final assetGrid = ImmichAssetGrid(
shrinkWrap: true,
renderList: renderList,
showDragScroll: false,
selectionActive: widget.selectionEnabled,
showMultiSelectIndicator: false,
listener: widget.selectionlistener,
visibleItemsListener: visibleItemsListener,
);
return Expanded(child: assetGrid);
},
error: (error, stackTrace) {
log.warning(
"Cannot get assets in the current map bounds ${error.toString()}",
error,
stackTrace,
);
return const SizedBox.shrink();
},
loading: () => const SizedBox.shrink(),
return Expanded(child: assetGrid);
},
error: (error, stackTrace) {
log.warning(
"Cannot get assets in the current map bounds ${error.toString()}",
error,
stackTrace,
);
return 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'),
),
);
},
),
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] : 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],
child: ColoredBox(
color: (widget.isDarkTheme
? Colors.grey[900]
: 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(
bottom: maxHeight * (0.14 + (currentExtend.value - 0.1)),
right: 15,
child: ElevatedButton(
onPressed: () =>
widget.bottomSheetEventSC.add(const MapPageZoomToLocation()),
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(12),
),
child: const Icon(
Icons.my_location,
size: 22,
fill: 1,
Positioned(
bottom: maxHeight * (0.14 + (currentExtend.value - 0.1)),
right: 15,
child: ElevatedButton(
onPressed: () => widget.bottomSheetEventSC
.add(const MapPageZoomToLocation()),
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(12),
),
child: const Icon(
Icons.my_location,
size: 22,
fill: 1,
),
),
),
),
],
],
),
),
);
}