This commit is contained in:
@@ -28,7 +28,7 @@ jobs:
|
|||||||
--tag "$IMAGE_SHA" \
|
--tag "$IMAGE_SHA" \
|
||||||
--tag "$IMAGE_LATEST" \
|
--tag "$IMAGE_LATEST" \
|
||||||
--build-arg MAPBOX_ACCESS_TOKEN="${{ secrets.MAPBOX_ACCESS_TOKEN }}" \
|
--build-arg MAPBOX_ACCESS_TOKEN="${{ secrets.MAPBOX_ACCESS_TOKEN }}" \
|
||||||
--build-arg MAPBOX_STYLE="mapbox/streets-v12" \
|
--build-arg MAPBOX_STYLE="mapbox/standard" \
|
||||||
--build-arg TELEGRAM_BOT_USERNAME="carfteebot" \
|
--build-arg TELEGRAM_BOT_USERNAME="carfteebot" \
|
||||||
--build-arg BUILD_VERSION="${GITHUB_SHA}" \
|
--build-arg BUILD_VERSION="${GITHUB_SHA}" \
|
||||||
. &&
|
. &&
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
FROM ghcr.io/cirruslabs/flutter:stable AS build
|
FROM ghcr.io/cirruslabs/flutter:stable AS build
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ARG MAPBOX_ACCESS_TOKEN=""
|
ARG MAPBOX_ACCESS_TOKEN=""
|
||||||
ARG MAPBOX_STYLE="mapbox/streets-v12"
|
ARG MAPBOX_STYLE="mapbox/standard"
|
||||||
ARG TELEGRAM_BOT_USERNAME="carfteebot"
|
ARG TELEGRAM_BOT_USERNAME="carfteebot"
|
||||||
ARG BUILD_VERSION="local"
|
ARG BUILD_VERSION="local"
|
||||||
COPY pubspec.* ./
|
COPY pubspec.* ./
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class PlaceState {
|
|||||||
return place;
|
return place;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return visiblePlaces.isEmpty ? null : visiblePlaces.first;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaceState copyWith({
|
PlaceState copyWith({
|
||||||
@@ -165,7 +165,7 @@ class PlaceCubit extends Cubit<PlaceViewState> {
|
|||||||
PlaceState(
|
PlaceState(
|
||||||
selectedTrait: null,
|
selectedTrait: null,
|
||||||
places: places,
|
places: places,
|
||||||
selectedPlaceId: places.isEmpty ? null : places.first.id,
|
selectedPlaceId: null,
|
||||||
currentUser: currentUser,
|
currentUser: currentUser,
|
||||||
hasTelegramAuth: _authRepository.hasTelegramAuth,
|
hasTelegramAuth: _authRepository.hasTelegramAuth,
|
||||||
userCoordinate: null,
|
userCoordinate: null,
|
||||||
@@ -201,10 +201,9 @@ class PlaceCubit extends Cubit<PlaceViewState> {
|
|||||||
|
|
||||||
void clearTrait() {
|
void clearTrait() {
|
||||||
final value = _requireReady();
|
final value = _requireReady();
|
||||||
final selectedPlaceId = value.places.isEmpty ? null : value.places.first.id;
|
|
||||||
emit(
|
emit(
|
||||||
PlaceViewState.ready(
|
PlaceViewState.ready(
|
||||||
value.copyWith(selectedTrait: null, selectedPlaceId: selectedPlaceId),
|
value.copyWith(selectedTrait: null, selectedPlaceId: null),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -337,12 +336,11 @@ class PlaceCubit extends Cubit<PlaceViewState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final places = await _placesRepository.fetchPlaces();
|
final places = await _placesRepository.fetchPlaces();
|
||||||
final selectedPlace = places.isEmpty ? null : places.first.id;
|
|
||||||
emit(
|
emit(
|
||||||
PlaceViewState.ready(
|
PlaceViewState.ready(
|
||||||
value.copyWith(
|
value.copyWith(
|
||||||
places: places,
|
places: places,
|
||||||
selectedPlaceId: selectedPlace,
|
selectedPlaceId: null,
|
||||||
reviewDraft: _emptyDraft,
|
reviewDraft: _emptyDraft,
|
||||||
voiceFilterTranscript: '',
|
voiceFilterTranscript: '',
|
||||||
voiceFilterTags: const [],
|
voiceFilterTags: const [],
|
||||||
|
|||||||
@@ -4,10 +4,10 @@ import 'dart:math' as math;
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_map/flutter_map.dart';
|
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:latlong2/latlong.dart' hide Path;
|
import 'package:latlong2/latlong.dart' hide Path;
|
||||||
|
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart' as mbx;
|
||||||
import 'package:waveform_flutter/waveform_flutter.dart' show Amplitude;
|
import 'package:waveform_flutter/waveform_flutter.dart' show Amplitude;
|
||||||
import 'package:waveform_recorder/waveform_recorder.dart';
|
import 'package:waveform_recorder/waveform_recorder.dart';
|
||||||
|
|
||||||
@@ -21,10 +21,9 @@ import '../data/places_repository.dart';
|
|||||||
import '../domain/place_models.dart';
|
import '../domain/place_models.dart';
|
||||||
import 'widgets/place_photo_card.dart';
|
import 'widgets/place_photo_card.dart';
|
||||||
|
|
||||||
const _mapboxAccessToken = String.fromEnvironment('MAPBOX_ACCESS_TOKEN');
|
|
||||||
const _mapboxStyle = String.fromEnvironment(
|
const _mapboxStyle = String.fromEnvironment(
|
||||||
'MAPBOX_STYLE',
|
'MAPBOX_STYLE',
|
||||||
defaultValue: 'mapbox/streets-v12',
|
defaultValue: 'mapbox/standard',
|
||||||
);
|
);
|
||||||
|
|
||||||
class MapflowShell extends StatelessWidget {
|
class MapflowShell extends StatelessWidget {
|
||||||
@@ -51,18 +50,24 @@ class MapflowShell extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MapContent extends StatelessWidget {
|
class _MapContent extends StatefulWidget {
|
||||||
const _MapContent({required this.state});
|
const _MapContent({required this.state});
|
||||||
|
|
||||||
static const _fallbackCenter = LatLng(10.7718, 106.6982);
|
|
||||||
|
|
||||||
final PlaceState state;
|
final PlaceState state;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_MapContent> createState() => _MapContentState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MapContentState extends State<_MapContent> {
|
||||||
|
static const _fallbackCenter = LatLng(16.0544, 108.2022);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final state = widget.state;
|
||||||
final selected = state.selectedPlace;
|
final selected = state.selectedPlace;
|
||||||
final userCoordinate = state.userCoordinate;
|
final userCoordinate = state.userCoordinate;
|
||||||
final mapCenter = userCoordinate ?? selected?.coordinate ?? _fallbackCenter;
|
final mapCenter = _focusCenter(state) ?? _fallbackCenter;
|
||||||
final placeCubit = context.read<PlaceCubit>();
|
final placeCubit = context.read<PlaceCubit>();
|
||||||
final traitCounts = _countPlaceTraits(state.places);
|
final traitCounts = _countPlaceTraits(state.places);
|
||||||
final availableTraits = [
|
final availableTraits = [
|
||||||
@@ -81,38 +86,13 @@ class _MapContent extends StatelessWidget {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Stack(
|
body: Stack(
|
||||||
children: [
|
children: [
|
||||||
FlutterMap(
|
_MapboxMapLayer(
|
||||||
options: MapOptions(
|
|
||||||
initialCenter: mapCenter,
|
initialCenter: mapCenter,
|
||||||
initialZoom: 14.2,
|
focusCenter: _focusCenter(state),
|
||||||
minZoom: 3,
|
places: state.recommendations,
|
||||||
maxZoom: 18,
|
selectedPlaceId: selected?.id,
|
||||||
),
|
userCoordinate: userCoordinate,
|
||||||
children: [
|
onPlaceTap: (place) => _selectAndShowPlace(context, place),
|
||||||
const _BaseMapTileLayer(),
|
|
||||||
MarkerLayer(
|
|
||||||
markers: [
|
|
||||||
for (final place in state.recommendations)
|
|
||||||
Marker(
|
|
||||||
width: 52,
|
|
||||||
height: 52,
|
|
||||||
point: place.coordinate,
|
|
||||||
child: _PlaceMarker(
|
|
||||||
selected: selected?.id == place.id,
|
|
||||||
onTap: () => _selectAndShowPlace(context, place),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (userCoordinate != null)
|
|
||||||
Marker(
|
|
||||||
width: 30,
|
|
||||||
height: 30,
|
|
||||||
point: userCoordinate,
|
|
||||||
child: const _UserLocationMarker(),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
const _MapAttribution(),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
SafeArea(
|
SafeArea(
|
||||||
child: Align(
|
child: Align(
|
||||||
@@ -183,6 +163,10 @@ class _MapContent extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LatLng? _focusCenter(PlaceState state) {
|
||||||
|
return state.userCoordinate ?? state.selectedPlace?.coordinate;
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _openSearchSheet(
|
Future<void> _openSearchSheet(
|
||||||
BuildContext context, {
|
BuildContext context, {
|
||||||
required List<PlaceTrait> traits,
|
required List<PlaceTrait> traits,
|
||||||
@@ -314,6 +298,169 @@ class _UserLocationMarker extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _ProjectedMarker {
|
||||||
|
const _ProjectedMarker({required this.place, required this.offset});
|
||||||
|
|
||||||
|
final PlaceRecommendation place;
|
||||||
|
final Offset offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MapboxMapLayer extends StatefulWidget {
|
||||||
|
const _MapboxMapLayer({
|
||||||
|
required this.initialCenter,
|
||||||
|
required this.focusCenter,
|
||||||
|
required this.places,
|
||||||
|
required this.selectedPlaceId,
|
||||||
|
required this.userCoordinate,
|
||||||
|
required this.onPlaceTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
final LatLng initialCenter;
|
||||||
|
final LatLng? focusCenter;
|
||||||
|
final List<PlaceRecommendation> places;
|
||||||
|
final String? selectedPlaceId;
|
||||||
|
final LatLng? userCoordinate;
|
||||||
|
final ValueChanged<PlaceRecommendation> onPlaceTap;
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<_MapboxMapLayer> createState() => _MapboxMapLayerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MapboxMapLayerState extends State<_MapboxMapLayer> {
|
||||||
|
mbx.MapboxMap? _mapboxMap;
|
||||||
|
var _mapLoaded = false;
|
||||||
|
var _didInitialFlyIn = false;
|
||||||
|
var _projectionVersion = 0;
|
||||||
|
LatLng? _lastFocusCenter;
|
||||||
|
List<_ProjectedMarker> _projectedPlaces = const [];
|
||||||
|
Offset? _projectedUserCoordinate;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void didUpdateWidget(covariant _MapboxMapLayer oldWidget) {
|
||||||
|
super.didUpdateWidget(oldWidget);
|
||||||
|
_updateCameraForFocus();
|
||||||
|
unawaited(_projectMarkers());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
mbx.MapWidget(
|
||||||
|
styleUri: _mapboxStyleUri,
|
||||||
|
viewport: mbx.CameraViewportState(
|
||||||
|
center: _mapboxPoint(widget.initialCenter),
|
||||||
|
zoom: _didInitialFlyIn ? 14.8 : 1.25,
|
||||||
|
bearing: _didInitialFlyIn ? -16 : 0,
|
||||||
|
pitch: _didInitialFlyIn ? 62 : 0,
|
||||||
|
),
|
||||||
|
onMapCreated: _onMapCreated,
|
||||||
|
onMapLoadedListener: (_) {
|
||||||
|
_mapLoaded = true;
|
||||||
|
_updateCameraForFocus();
|
||||||
|
unawaited(_projectMarkers());
|
||||||
|
},
|
||||||
|
onCameraChangeListener: (_) => unawaited(_projectMarkers()),
|
||||||
|
onMapIdleListener: (_) => unawaited(_projectMarkers()),
|
||||||
|
),
|
||||||
|
for (final projected in _projectedPlaces)
|
||||||
|
Positioned(
|
||||||
|
left: projected.offset.dx - 26,
|
||||||
|
top: projected.offset.dy - 26,
|
||||||
|
width: 52,
|
||||||
|
height: 52,
|
||||||
|
child: _PlaceMarker(
|
||||||
|
selected: projected.place.id == widget.selectedPlaceId,
|
||||||
|
onTap: () => widget.onPlaceTap(projected.place),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
if (_projectedUserCoordinate != null)
|
||||||
|
Positioned(
|
||||||
|
left: _projectedUserCoordinate!.dx - 15,
|
||||||
|
top: _projectedUserCoordinate!.dy - 15,
|
||||||
|
width: 30,
|
||||||
|
height: 30,
|
||||||
|
child: const _UserLocationMarker(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onMapCreated(mbx.MapboxMap mapboxMap) {
|
||||||
|
_mapboxMap = mapboxMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateCameraForFocus() {
|
||||||
|
final mapboxMap = _mapboxMap;
|
||||||
|
final focusCenter = widget.focusCenter;
|
||||||
|
if (!_mapLoaded || mapboxMap == null || focusCenter == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (focusCenter == _lastFocusCenter) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_lastFocusCenter = focusCenter;
|
||||||
|
final camera = mbx.CameraOptions(
|
||||||
|
center: _mapboxPoint(focusCenter),
|
||||||
|
zoom: 14.8,
|
||||||
|
bearing: -16,
|
||||||
|
pitch: 62,
|
||||||
|
);
|
||||||
|
if (_didInitialFlyIn) {
|
||||||
|
unawaited(
|
||||||
|
mapboxMap.easeTo(camera, mbx.MapAnimationOptions(duration: 900)),
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_didInitialFlyIn = true;
|
||||||
|
unawaited(mapboxMap.flyTo(camera, mbx.MapAnimationOptions(duration: 2600)));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _projectMarkers() async {
|
||||||
|
final mapboxMap = _mapboxMap;
|
||||||
|
if (!_mapLoaded || mapboxMap == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final version = ++_projectionVersion;
|
||||||
|
final coordinates = [
|
||||||
|
for (final place in widget.places) _mapboxPoint(place.coordinate),
|
||||||
|
if (widget.userCoordinate != null) _mapboxPoint(widget.userCoordinate!),
|
||||||
|
];
|
||||||
|
if (coordinates.isEmpty) {
|
||||||
|
if (!mounted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
_projectedPlaces = const [];
|
||||||
|
_projectedUserCoordinate = null;
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final pixels = await mapboxMap.pixelsForCoordinates(coordinates);
|
||||||
|
if (!mounted || version != _projectionVersion) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
_projectedPlaces = [
|
||||||
|
for (var index = 0; index < widget.places.length; index++)
|
||||||
|
_ProjectedMarker(
|
||||||
|
place: widget.places[index],
|
||||||
|
offset: Offset(pixels[index].x, pixels[index].y),
|
||||||
|
),
|
||||||
|
];
|
||||||
|
_projectedUserCoordinate = widget.userCoordinate == null
|
||||||
|
? null
|
||||||
|
: Offset(pixels.last.x, pixels.last.y);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class _UserAvatar extends StatelessWidget {
|
class _UserAvatar extends StatelessWidget {
|
||||||
const _UserAvatar({
|
const _UserAvatar({
|
||||||
required this.user,
|
required this.user,
|
||||||
@@ -916,12 +1063,13 @@ class _MapError extends StatelessWidget {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
body: Stack(
|
body: Stack(
|
||||||
children: [
|
children: [
|
||||||
FlutterMap(
|
const _MapboxMapLayer(
|
||||||
options: const MapOptions(
|
initialCenter: LatLng(16.0544, 108.2022),
|
||||||
initialCenter: LatLng(10.7718, 106.6982),
|
focusCenter: LatLng(16.0544, 108.2022),
|
||||||
initialZoom: 14.2,
|
places: [],
|
||||||
),
|
selectedPlaceId: null,
|
||||||
children: [const _BaseMapTileLayer(), const _MapAttribution()],
|
userCoordinate: null,
|
||||||
|
onPlaceTap: _ignorePlaceTap,
|
||||||
),
|
),
|
||||||
SafeArea(
|
SafeArea(
|
||||||
child: Align(
|
child: Align(
|
||||||
@@ -944,50 +1092,22 @@ class _MapError extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BaseMapTileLayer extends StatelessWidget {
|
void _ignorePlaceTap(PlaceRecommendation _) {}
|
||||||
const _BaseMapTileLayer();
|
|
||||||
|
|
||||||
static const _osmUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
|
mbx.Point _mapboxPoint(LatLng coordinate) {
|
||||||
|
return mbx.Point(
|
||||||
@override
|
coordinates: mbx.Position(coordinate.longitude, coordinate.latitude),
|
||||||
Widget build(BuildContext context) {
|
|
||||||
if (_mapboxAccessToken.isEmpty) {
|
|
||||||
return TileLayer(
|
|
||||||
urlTemplate: _osmUrl,
|
|
||||||
userAgentPackageName: 'com.mapflow.app',
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return TileLayer(
|
|
||||||
urlTemplate:
|
|
||||||
'https://api.mapbox.com/styles/v1/$_mapboxStyle/tiles/512/{z}/{x}/{y}@2x'
|
|
||||||
'?access_token=$_mapboxAccessToken',
|
|
||||||
tileDimension: 512,
|
|
||||||
zoomOffset: -1,
|
|
||||||
maxNativeZoom: 22,
|
|
||||||
userAgentPackageName: 'com.mapflow.app',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _MapAttribution extends StatelessWidget {
|
String get _mapboxStyleUri {
|
||||||
const _MapAttribution();
|
if (_mapboxStyle.startsWith('mapbox://')) {
|
||||||
|
return _mapboxStyle;
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
if (_mapboxAccessToken.isEmpty) {
|
|
||||||
return const RichAttributionWidget(
|
|
||||||
attributions: [TextSourceAttribution('OpenStreetMap contributors')],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
if (_mapboxStyle.startsWith('mapbox/')) {
|
||||||
return const RichAttributionWidget(
|
return 'mapbox://styles/$_mapboxStyle';
|
||||||
attributions: [
|
|
||||||
TextSourceAttribution('Mapbox', prependCopyright: false),
|
|
||||||
TextSourceAttribution('OpenStreetMap contributors'),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
return _mapboxStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
class _TraitPickerSheet extends StatelessWidget {
|
class _TraitPickerSheet extends StatelessWidget {
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_web_plugins/url_strategy.dart';
|
import 'package:flutter_web_plugins/url_strategy.dart';
|
||||||
|
import 'package:mapbox_maps_flutter/mapbox_maps_flutter.dart' as mbx;
|
||||||
|
|
||||||
import 'app/app.dart';
|
import 'app/app.dart';
|
||||||
import 'shared/auth/telegram_session.dart' as telegram_session;
|
import 'shared/auth/telegram_session.dart' as telegram_session;
|
||||||
|
|
||||||
|
const _mapboxAccessToken = String.fromEnvironment('MAPBOX_ACCESS_TOKEN');
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
if (_mapboxAccessToken.isNotEmpty) {
|
||||||
|
mbx.MapboxOptions.setAccessToken(_mapboxAccessToken);
|
||||||
|
}
|
||||||
usePathUrlStrategy();
|
usePathUrlStrategy();
|
||||||
telegram_session.configureTelegramWebApp();
|
telegram_session.configureTelegramWebApp();
|
||||||
runApp(const MapflowApp());
|
runApp(const MapflowApp());
|
||||||
|
|||||||
+104
@@ -41,6 +41,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.13.1"
|
version: "2.13.1"
|
||||||
|
benchmark:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: benchmark
|
||||||
|
sha256: cb3eeea01e3f054df76ee9775ca680f3afa5f19f39b2bb426ba78ba27654493b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.3.0"
|
||||||
bloc:
|
bloc:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -209,6 +217,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
|
dart_sort_queue:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dart_sort_queue
|
||||||
|
sha256: f3353ba8b4850e072d3368757f62edb79af34a9703c3e3df9c59342721f5f5b1
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.2+3"
|
||||||
dart_style:
|
dart_style:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -342,6 +358,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "8.3.0"
|
version: "8.3.0"
|
||||||
|
flutter_plugin_android_lifecycle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_plugin_android_lifecycle
|
||||||
|
sha256: "3854fe5e3bff0b113c658f260b90c95dea17c92db0f2addeac2e343dd9969785"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.35"
|
||||||
flutter_svg:
|
flutter_svg:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -424,6 +448,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.5"
|
version: "0.2.5"
|
||||||
|
geotypes:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: geotypes
|
||||||
|
sha256: "5bedf57de92283133dd221e363812ef50eaaba414f0823b1974ef7d84b86991f"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.2"
|
||||||
glob:
|
glob:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -640,6 +672,38 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0"
|
version: "1.3.0"
|
||||||
|
mapbox_maps_flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: mapbox_maps_flutter
|
||||||
|
sha256: f98e3808113088c6e0bc60f592d23eb5a23215b10a9389754642c8e5f9bdc117
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0-alpha.1"
|
||||||
|
mapbox_maps_flutter_mobile:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: mapbox_maps_flutter_mobile
|
||||||
|
sha256: "4ef1a6cb23dfe4a6f5bb896ea7b1195dd474aaffd056bab77434fda03bc9446b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0-alpha.1"
|
||||||
|
mapbox_maps_flutter_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: mapbox_maps_flutter_platform_interface
|
||||||
|
sha256: e64dc1df85cb2fe5c7d704771a01e53b6d6ccdafb8be70c2879c0d7e8bf6cbd8
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0-alpha.1"
|
||||||
|
mapbox_maps_flutter_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: mapbox_maps_flutter_web
|
||||||
|
sha256: "01ef5f2b4578e33cbdae27d05b7b9aa37246b205746a552f507d66b0deaf20cc"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0-alpha.1"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -880,6 +944,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.0"
|
version: "1.5.0"
|
||||||
|
rbush:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: rbush
|
||||||
|
sha256: "48b683421b4afb43a642f82c6aa31911e54f3069143d31c7d33cbe329df13403"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.1"
|
||||||
record:
|
record:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1045,6 +1117,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.5"
|
version: "0.1.5"
|
||||||
|
sweepline_intersections:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sweepline_intersections
|
||||||
|
sha256: a665c707200a4f07140a4029b41a7c4883beb3f04322cd8e08ebf650f69e1176
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.4"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -1061,6 +1141,30 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.10"
|
version: "0.7.10"
|
||||||
|
turf:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: turf
|
||||||
|
sha256: "7684654c561e751332bc2fa6e9bb7bcf0c71bad5315acf126206e7ecfef67256"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.12"
|
||||||
|
turf_equality:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: turf_equality
|
||||||
|
sha256: f0f44ffe389547941358e0d3d4a747db2bd56115b32ff1cede5e5bdf3126a3e2
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.0"
|
||||||
|
turf_pip:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: turf_pip
|
||||||
|
sha256: ba4fd414baffd5d7b30880658ad6db82461c49ec023f8ffd0c23d398ad8b14be
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.2"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ dependencies:
|
|||||||
gql_code_builder_serializers: ^0.1.0+1
|
gql_code_builder_serializers: ^0.1.0+1
|
||||||
built_collection: ^5.1.1
|
built_collection: ^5.1.1
|
||||||
built_value: ^8.12.6
|
built_value: ^8.12.6
|
||||||
|
mapbox_maps_flutter: ^3.0.0-alpha.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user