only geolocate and show maps when connected
This commit is contained in:
parent
a85612269a
commit
8b1d37fc32
9 changed files with 137 additions and 40 deletions
28
lib/model/connectivity.dart
Normal file
28
lib/model/connectivity.dart
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import 'package:connectivity/connectivity.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
final AvesConnectivity connectivity = AvesConnectivity._private();
|
||||||
|
|
||||||
|
class AvesConnectivity {
|
||||||
|
bool _isConnected;
|
||||||
|
|
||||||
|
AvesConnectivity._private() {
|
||||||
|
Connectivity().onConnectivityChanged.listen(_updateFromResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onResume() => _isConnected = null;
|
||||||
|
|
||||||
|
Future<bool> get isConnected async {
|
||||||
|
if (_isConnected != null) return SynchronousFuture(_isConnected);
|
||||||
|
final result = await (Connectivity().checkConnectivity());
|
||||||
|
_updateFromResult(result);
|
||||||
|
return _isConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> get canGeolocate => isConnected;
|
||||||
|
|
||||||
|
void _updateFromResult(ConnectivityResult result) {
|
||||||
|
_isConnected = result != ConnectivityResult.none;
|
||||||
|
debugPrint('Device is connected=$_isConnected');
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aves/model/filters/location.dart';
|
import 'package:aves/model/connectivity.dart';
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
|
import 'package:aves/model/filters/location.dart';
|
||||||
import 'package:aves/model/metadata.dart';
|
import 'package:aves/model/metadata.dart';
|
||||||
import 'package:aves/model/metadata_db.dart';
|
import 'package:aves/model/metadata_db.dart';
|
||||||
import 'package:aves/model/source/collection_source.dart';
|
import 'package:aves/model/source/collection_source.dart';
|
||||||
|
@ -27,6 +28,8 @@ mixin LocationMixin on SourceBase {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> locateEntries() async {
|
Future<void> locateEntries() async {
|
||||||
|
if (!(await connectivity.canGeolocate)) return;
|
||||||
|
|
||||||
// final stopwatch = Stopwatch()..start();
|
// final stopwatch = Stopwatch()..start();
|
||||||
final byLocated = groupBy<AvesEntry, bool>(rawEntries.where((entry) => entry.hasGps), (entry) => entry.isLocated);
|
final byLocated = groupBy<AvesEntry, bool>(rawEntries.where((entry) => entry.hasGps), (entry) => entry.isLocated);
|
||||||
final todo = byLocated[false] ?? [];
|
final todo = byLocated[false] ?? [];
|
||||||
|
|
|
@ -29,14 +29,14 @@ class Constants {
|
||||||
Dependency(
|
Dependency(
|
||||||
name: 'AndroidX Core-KTX',
|
name: 'AndroidX Core-KTX',
|
||||||
license: 'Apache 2.0',
|
license: 'Apache 2.0',
|
||||||
licenseUrl: 'https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/LICENSE.txt',
|
licenseUrl: 'https://android.googlesource.com/platform/frameworks/support/+/androidx-main/LICENSE.txt',
|
||||||
sourceUrl: 'https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/core/core-ktx',
|
sourceUrl: 'https://android.googlesource.com/platform/frameworks/support/+/androidx-main/core/core-ktx',
|
||||||
),
|
),
|
||||||
Dependency(
|
Dependency(
|
||||||
name: 'AndroidX Exifinterface',
|
name: 'AndroidX Exifinterface',
|
||||||
license: 'Apache 2.0',
|
license: 'Apache 2.0',
|
||||||
licenseUrl: 'https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/LICENSE.txt',
|
licenseUrl: 'https://android.googlesource.com/platform/frameworks/support/+/androidx-main/LICENSE.txt',
|
||||||
sourceUrl: 'https://android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/exifinterface/exifinterface',
|
sourceUrl: 'https://android.googlesource.com/platform/frameworks/support/+/androidx-main/exifinterface/exifinterface',
|
||||||
),
|
),
|
||||||
Dependency(
|
Dependency(
|
||||||
name: 'Android-TiffBitmapFactory',
|
name: 'Android-TiffBitmapFactory',
|
||||||
|
@ -83,6 +83,12 @@ class Constants {
|
||||||
licenseUrl: 'https://github.com/dart-lang/collection/blob/master/LICENSE',
|
licenseUrl: 'https://github.com/dart-lang/collection/blob/master/LICENSE',
|
||||||
sourceUrl: 'https://github.com/dart-lang/collection',
|
sourceUrl: 'https://github.com/dart-lang/collection',
|
||||||
),
|
),
|
||||||
|
Dependency(
|
||||||
|
name: 'Connectivity',
|
||||||
|
license: 'BSD 3-Clause',
|
||||||
|
licenseUrl: 'https://github.com/flutter/plugins/blob/master/packages/connectivity/connectivity/LICENSE',
|
||||||
|
sourceUrl: 'https://github.com/flutter/plugins/blob/master/packages/connectivity/connectivity',
|
||||||
|
),
|
||||||
Dependency(
|
Dependency(
|
||||||
name: 'Decorated Icon',
|
name: 'Decorated Icon',
|
||||||
license: 'MIT',
|
license: 'MIT',
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'package:aves/main.dart';
|
import 'package:aves/main.dart';
|
||||||
|
import 'package:aves/model/connectivity.dart';
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/model/settings/home_page.dart';
|
import 'package:aves/model/settings/home_page.dart';
|
||||||
|
@ -111,9 +112,14 @@ class _HomePageState extends State<HomePage> {
|
||||||
Future<AvesEntry> _initViewerEntry({@required String uri, @required String mimeType}) async {
|
Future<AvesEntry> _initViewerEntry({@required String uri, @required String mimeType}) async {
|
||||||
final entry = await ImageFileService.getEntry(uri, mimeType);
|
final entry = await ImageFileService.getEntry(uri, mimeType);
|
||||||
if (entry != null) {
|
if (entry != null) {
|
||||||
// cataloguing is essential for geolocation and video rotation
|
// cataloguing is essential for coordinates and video rotation
|
||||||
await entry.catalog();
|
await entry.catalog();
|
||||||
unawaited(entry.locate());
|
// locating is fine in the background
|
||||||
|
unawaited(connectivity.canGeolocate.then((connected) {
|
||||||
|
if (connected) {
|
||||||
|
entry.locate();
|
||||||
|
}
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:aves/model/connectivity.dart';
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/source/collection_lens.dart';
|
import 'package:aves/model/source/collection_lens.dart';
|
||||||
import 'package:aves/widgets/common/magnifier/pan/scroll_physics.dart';
|
import 'package:aves/widgets/common/magnifier/pan/scroll_physics.dart';
|
||||||
|
@ -150,8 +151,12 @@ class _ViewerVerticalPageViewState extends State<ViewerVerticalPageView> {
|
||||||
entry.imageChangeNotifier.addListener(_onImageChanged);
|
entry.imageChangeNotifier.addListener(_onImageChanged);
|
||||||
// make sure to locate the entry,
|
// make sure to locate the entry,
|
||||||
// so that we can display the address instead of coordinates
|
// so that we can display the address instead of coordinates
|
||||||
// even when background locating has not reached this entry yet
|
// even when initial collection locating has not reached this entry yet
|
||||||
entry.locate();
|
connectivity.canGeolocate.then((connected) {
|
||||||
|
if (connected) {
|
||||||
|
entry.locate();
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:aves/model/connectivity.dart';
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
import 'package:aves/model/filters/filters.dart';
|
import 'package:aves/model/filters/filters.dart';
|
||||||
import 'package:aves/model/settings/screen_on.dart';
|
import 'package:aves/model/settings/screen_on.dart';
|
||||||
|
@ -141,8 +142,15 @@ class _EntryViewerStackState extends State<EntryViewerStack> with SingleTickerPr
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||||
if (state == AppLifecycleState.paused) {
|
switch (state) {
|
||||||
_pauseVideoControllers();
|
case AppLifecycleState.paused:
|
||||||
|
_pauseVideoControllers();
|
||||||
|
break;
|
||||||
|
case AppLifecycleState.resumed:
|
||||||
|
connectivity.onResume();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:aves/model/filters/location.dart';
|
import 'package:aves/model/connectivity.dart';
|
||||||
import 'package:aves/model/entry.dart';
|
import 'package:aves/model/entry.dart';
|
||||||
|
import 'package:aves/model/filters/location.dart';
|
||||||
import 'package:aves/model/settings/coordinate_format.dart';
|
import 'package:aves/model/settings/coordinate_format.dart';
|
||||||
import 'package:aves/model/settings/map_style.dart';
|
import 'package:aves/model/settings/map_style.dart';
|
||||||
import 'package:aves/model/settings/settings.dart';
|
import 'package:aves/model/settings/settings.dart';
|
||||||
|
@ -102,34 +103,40 @@ class _LocationSectionState extends State<LocationSection> with TickerProviderSt
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
if (widget.showTitle) SectionRow(AIcons.location),
|
if (widget.showTitle) SectionRow(AIcons.location),
|
||||||
NotificationListener(
|
FutureBuilder<bool>(
|
||||||
onNotification: (notification) {
|
future: connectivity.isConnected,
|
||||||
if (notification is MapStyleChangedNotification) setState(() {});
|
builder: (context, snapshot) {
|
||||||
return false;
|
if (snapshot.data != true) return SizedBox();
|
||||||
|
return NotificationListener(
|
||||||
|
onNotification: (notification) {
|
||||||
|
if (notification is MapStyleChangedNotification) setState(() {});
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
child: AnimatedSize(
|
||||||
|
alignment: Alignment.topCenter,
|
||||||
|
curve: Curves.easeInOutCubic,
|
||||||
|
duration: Durations.mapStyleSwitchAnimation,
|
||||||
|
vsync: this,
|
||||||
|
child: settings.infoMapStyle.isGoogleMaps
|
||||||
|
? EntryGoogleMap(
|
||||||
|
// `LatLng` used by `google_maps_flutter` is not the one from `latlong` package
|
||||||
|
latLng: Tuple2<double, double>(entry.latLng.latitude, entry.latLng.longitude),
|
||||||
|
geoUri: entry.geoUri,
|
||||||
|
initialZoom: settings.infoMapZoom,
|
||||||
|
markerId: entry.uri ?? entry.path,
|
||||||
|
markerBuilder: buildMarker,
|
||||||
|
)
|
||||||
|
: EntryLeafletMap(
|
||||||
|
latLng: entry.latLng,
|
||||||
|
geoUri: entry.geoUri,
|
||||||
|
initialZoom: settings.infoMapZoom,
|
||||||
|
style: settings.infoMapStyle,
|
||||||
|
markerSize: Size(extent, extent + pointerSize.height),
|
||||||
|
markerBuilder: buildMarker,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: AnimatedSize(
|
|
||||||
alignment: Alignment.topCenter,
|
|
||||||
curve: Curves.easeInOutCubic,
|
|
||||||
duration: Durations.mapStyleSwitchAnimation,
|
|
||||||
vsync: this,
|
|
||||||
child: settings.infoMapStyle.isGoogleMaps
|
|
||||||
? EntryGoogleMap(
|
|
||||||
// `LatLng` used by `google_maps_flutter` is not the one from `latlong` package
|
|
||||||
latLng: Tuple2<double, double>(entry.latLng.latitude, entry.latLng.longitude),
|
|
||||||
geoUri: entry.geoUri,
|
|
||||||
initialZoom: settings.infoMapZoom,
|
|
||||||
markerId: entry.uri ?? entry.path,
|
|
||||||
markerBuilder: buildMarker,
|
|
||||||
)
|
|
||||||
: EntryLeafletMap(
|
|
||||||
latLng: entry.latLng,
|
|
||||||
geoUri: entry.geoUri,
|
|
||||||
initialZoom: settings.infoMapZoom,
|
|
||||||
style: settings.infoMapStyle,
|
|
||||||
markerSize: Size(extent, extent + pointerSize.height),
|
|
||||||
markerBuilder: buildMarker,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
if (entry.hasGps) _AddressInfoGroup(entry: entry),
|
if (entry.hasGps) _AddressInfoGroup(entry: entry),
|
||||||
if (filters.isNotEmpty)
|
if (filters.isNotEmpty)
|
||||||
|
@ -174,7 +181,12 @@ class _AddressInfoGroupState extends State<_AddressInfoGroup> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_addressLineLoader = entry.findAddressLine();
|
_addressLineLoader = connectivity.canGeolocate.then((connected) {
|
||||||
|
if (connected) {
|
||||||
|
return entry.findAddressLine();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
28
pubspec.lock
28
pubspec.lock
|
@ -113,6 +113,34 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0-nullsafety.3"
|
version: "1.15.0-nullsafety.3"
|
||||||
|
connectivity:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: connectivity
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.2"
|
||||||
|
connectivity_for_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: connectivity_for_web
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.1+4"
|
||||||
|
connectivity_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: connectivity_macos
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.0+7"
|
||||||
|
connectivity_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: connectivity_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.6"
|
||||||
console_log_handler:
|
console_log_handler:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -33,6 +33,7 @@ dependencies:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
charts_flutter:
|
charts_flutter:
|
||||||
collection:
|
collection:
|
||||||
|
connectivity:
|
||||||
decorated_icon:
|
decorated_icon:
|
||||||
event_bus:
|
event_bus:
|
||||||
expansion_tile_card:
|
expansion_tile_card:
|
||||||
|
|
Loading…
Reference in a new issue