info: improved loading of location & metadata sections
This commit is contained in:
parent
6feb1efb13
commit
a5115fb83b
6 changed files with 145 additions and 57 deletions
|
@ -1,7 +1,14 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
final Map<String, Color> _stringColors = {};
|
||||
|
||||
Color stringToColor(String string, {double saturation = .8, double lightness = .6}) {
|
||||
var color = _stringColors[string];
|
||||
if (color == null) {
|
||||
final hash = string.codeUnits.fold(0, (prev, el) => prev = el + ((prev << 5) - prev));
|
||||
final hue = (hash % 360).toDouble();
|
||||
return HSLColor.fromAHSL(1.0, hue, saturation, lightness).toColor();
|
||||
color = HSLColor.fromAHSL(1.0, hue, saturation, lightness).toColor();
|
||||
_stringColors[string] = color;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import 'package:aves/utils/android_app_service.dart';
|
|||
import 'package:aves/utils/geo_utils.dart';
|
||||
import 'package:aves/widgets/common/aves_filter_chip.dart';
|
||||
import 'package:aves/widgets/fullscreen/info/info_page.dart';
|
||||
import 'package:aves/widgets/fullscreen/info/map_initializer.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:outline_material_icons/outline_material_icons.dart';
|
||||
|
@ -168,13 +169,15 @@ class ImageMapState extends State<ImageMap> with AutomaticKeepAliveClientMixin {
|
|||
return Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SizedBox(
|
||||
height: 200,
|
||||
child: ClipRRect(
|
||||
borderRadius: const BorderRadius.all(
|
||||
Radius.circular(16),
|
||||
),
|
||||
child: GoogleMap(
|
||||
child: Container(
|
||||
color: Colors.white70,
|
||||
height: 200,
|
||||
child: GoogleMapInitializer(
|
||||
builder: (context) => GoogleMap(
|
||||
initialCameraPosition: CameraPosition(
|
||||
target: widget.latLng,
|
||||
zoom: widget.initialZoom,
|
||||
|
@ -197,6 +200,7 @@ class ImageMapState extends State<ImageMap> with AutomaticKeepAliveClientMixin {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Column(children: [
|
||||
IconButton(
|
||||
|
|
65
lib/widgets/fullscreen/info/map_initializer.dart
Normal file
65
lib/widgets/fullscreen/info/map_initializer.dart
Normal file
|
@ -0,0 +1,65 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
// workaround to Google Maps initialization blocking the dart thread
|
||||
// cf https://github.com/flutter/flutter/issues/28493
|
||||
// it loads first Google Maps in an isolate, and then build the desired map
|
||||
|
||||
class GoogleMapInitializer extends StatefulWidget {
|
||||
final WidgetBuilder builder, errorBuilder, placeholderBuilder;
|
||||
|
||||
const GoogleMapInitializer({
|
||||
@required this.builder,
|
||||
this.errorBuilder,
|
||||
this.placeholderBuilder,
|
||||
});
|
||||
|
||||
@override
|
||||
_GoogleMapInitializerState createState() => _GoogleMapInitializerState();
|
||||
}
|
||||
|
||||
class _GoogleMapInitializerState extends State<GoogleMapInitializer> {
|
||||
Future<void> initializer;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
initializer = compute(_preload, null);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder(
|
||||
future: initializer,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasError) {
|
||||
return widget.errorBuilder?.call(context) ?? const Icon(Icons.error_outline);
|
||||
} else if (snapshot.connectionState == ConnectionState.done) {
|
||||
return widget.builder(context);
|
||||
} else {
|
||||
return widget.placeholderBuilder?.call(context) ?? const SizedBox.shrink();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _preload(_) async {
|
||||
final mapCreatedCompleter = Completer();
|
||||
GoogleMap(
|
||||
compassEnabled: false,
|
||||
mapToolbarEnabled: false,
|
||||
rotateGesturesEnabled: false,
|
||||
scrollGesturesEnabled: false,
|
||||
zoomGesturesEnabled: false,
|
||||
tiltGesturesEnabled: false,
|
||||
buildingsEnabled: false,
|
||||
initialCameraPosition: const CameraPosition(target: LatLng(0, 0), zoom: 20),
|
||||
onMapCreated: (controller) => mapCreatedCompleter.complete(),
|
||||
);
|
||||
return mapCreatedCompleter.future;
|
||||
}
|
|
@ -6,6 +6,7 @@ import 'package:aves/model/metadata_service.dart';
|
|||
import 'package:aves/utils/color_utils.dart';
|
||||
import 'package:aves/widgets/common/fx/highlight_decoration.dart';
|
||||
import 'package:aves/widgets/fullscreen/info/info_page.dart';
|
||||
import 'package:expansion_tile_card/expansion_tile_card.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:outline_material_icons/outline_material_icons.dart';
|
||||
|
||||
|
@ -63,37 +64,36 @@ class _MetadataSectionSliverState extends State<MetadataSectionSliver> with Auto
|
|||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
|
||||
final directoriesWithoutTitle = _metadata.where((dir) => dir.name.isEmpty);
|
||||
final directoriesWithTitle = _metadata.where((dir) => dir.name.isNotEmpty);
|
||||
if (_metadata.isEmpty) return const SliverToBoxAdapter(child: SizedBox.shrink());
|
||||
|
||||
final directoriesWithoutTitle = _metadata.where((dir) => dir.name.isEmpty).toList();
|
||||
final directoriesWithTitle = _metadata.where((dir) => dir.name.isNotEmpty).toList();
|
||||
final untitledDirectoryCount = directoriesWithoutTitle.length;
|
||||
return SliverList(
|
||||
delegate: SliverChildListDelegate(
|
||||
[
|
||||
if (_metadata.isNotEmpty) const SectionRow(OMIcons.info),
|
||||
...directoriesWithoutTitle.map((dir) => InfoRowGroup(dir.tags)),
|
||||
Theme(
|
||||
data: Theme.of(context).copyWith(cardColor: Colors.grey[900]),
|
||||
child: ExpansionPanelList.radio(
|
||||
key: ValueKey(widget.entry.uri),
|
||||
expandedHeaderPadding: EdgeInsets.zero,
|
||||
children: directoriesWithTitle.map<ExpansionPanelRadio>((dir) {
|
||||
return ExpansionPanelRadio(
|
||||
value: dir.name,
|
||||
canTapOnHeader: true,
|
||||
headerBuilder: (BuildContext context, bool isExpanded) {
|
||||
return ListTile(
|
||||
delegate: SliverChildBuilderDelegate(
|
||||
(context, index) {
|
||||
if (index == 0) {
|
||||
return const SectionRow(OMIcons.info);
|
||||
}
|
||||
if (index < untitledDirectoryCount + 1) {
|
||||
final dir = directoriesWithoutTitle[index - 1];
|
||||
return InfoRowGroup(dir.tags);
|
||||
}
|
||||
final dir = directoriesWithTitle[index - 1 - untitledDirectoryCount];
|
||||
return ExpansionTileCard(
|
||||
title: _DirectoryTitle(dir.name),
|
||||
);
|
||||
},
|
||||
body: Container(
|
||||
children: [
|
||||
const Divider(thickness: 1.0, height: 1.0),
|
||||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: InfoRowGroup(dir.tags),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
)
|
||||
],
|
||||
baseColor: Colors.grey[900],
|
||||
);
|
||||
},
|
||||
childCount: 1 + _metadata.length,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -143,6 +143,7 @@ class _DirectoryTitle extends StatelessWidget {
|
|||
child: Text(
|
||||
name,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: Colors.black,
|
||||
|
@ -153,6 +154,9 @@ class _DirectoryTitle extends StatelessWidget {
|
|||
fontSize: 18,
|
||||
fontFamily: 'Concourse Caps',
|
||||
),
|
||||
softWrap: false,
|
||||
overflow: TextOverflow.fade,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -101,6 +101,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
expansion_tile_card:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: expansion_tile_card
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
flushbar:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
@ -23,6 +23,7 @@ dependencies:
|
|||
git:
|
||||
url: git://github.com/deckerst/flutter-draggable-scrollbar.git
|
||||
event_bus:
|
||||
expansion_tile_card:
|
||||
flushbar:
|
||||
# flushbar-1.9.1 cannot be built with Flutter 1.15.17
|
||||
git:
|
||||
|
|
Loading…
Reference in a new issue