Use Mapbox tiles for web map
All checks were successful
Build and deploy Flutter Web / build (push) Successful in 3m25s

This commit is contained in:
Ruslan Bakiev
2026-05-08 16:30:56 +07:00
parent 277888c407
commit deba48185a
3 changed files with 71 additions and 19 deletions

View File

@@ -31,7 +31,12 @@ jobs:
fi fi
docker buildx use "$builder" docker buildx use "$builder"
docker buildx inspect --bootstrap docker buildx inspect --bootstrap
docker buildx build --push --tag "$IMAGE" . docker buildx build \
--push \
--tag "$IMAGE" \
--build-arg MAPBOX_ACCESS_TOKEN="${{ secrets.MAPBOX_ACCESS_TOKEN }}" \
--build-arg MAPBOX_STYLE="mapbox/streets-v12" \
.
- name: Skip stale deployment - name: Skip stale deployment
run: | run: |

View File

@@ -1,9 +1,13 @@
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_STYLE="mapbox/streets-v12"
COPY pubspec.* ./ COPY pubspec.* ./
RUN flutter pub get RUN flutter pub get
COPY . . COPY . .
RUN flutter build web --release RUN flutter build web --release \
--dart-define=MAPBOX_ACCESS_TOKEN="$MAPBOX_ACCESS_TOKEN" \
--dart-define=MAPBOX_STYLE="$MAPBOX_STYLE"
FROM nginx:1.27-alpine FROM nginx:1.27-alpine
COPY nginx.conf /etc/nginx/conf.d/default.conf COPY nginx.conf /etc/nginx/conf.d/default.conf

View File

@@ -8,6 +8,12 @@ import 'package:latlong2/latlong.dart';
import '../models/place_models.dart'; import '../models/place_models.dart';
import '../state/place_controller.dart'; import '../state/place_controller.dart';
const _mapboxAccessToken = String.fromEnvironment('MAPBOX_ACCESS_TOKEN');
const _mapboxStyle = String.fromEnvironment(
'MAPBOX_STYLE',
defaultValue: 'mapbox/streets-v12',
);
class MapflowShell extends ConsumerWidget { class MapflowShell extends ConsumerWidget {
const MapflowShell({super.key}); const MapflowShell({super.key});
@@ -45,10 +51,7 @@ class _MapContent extends ConsumerWidget {
maxZoom: 18, maxZoom: 18,
), ),
children: [ children: [
TileLayer( const _BaseMapTileLayer(),
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
userAgentPackageName: 'com.mapflow.app',
),
MarkerLayer( MarkerLayer(
markers: [ markers: [
for (final place in state.recommendations) for (final place in state.recommendations)
@@ -65,11 +68,7 @@ class _MapContent extends ConsumerWidget {
), ),
], ],
), ),
const RichAttributionWidget( const _MapAttribution(),
attributions: [
TextSourceAttribution('OpenStreetMap contributors'),
],
),
], ],
), ),
SafeArea( SafeArea(
@@ -131,10 +130,8 @@ class _MapLoading extends StatelessWidget {
initialZoom: 14.2, initialZoom: 14.2,
), ),
children: [ children: [
TileLayer( const _BaseMapTileLayer(),
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', const _MapAttribution(),
userAgentPackageName: 'com.mapflow.app',
),
], ],
), ),
const Center(child: CircularProgressIndicator()), const Center(child: CircularProgressIndicator()),
@@ -160,10 +157,8 @@ class _MapError extends StatelessWidget {
initialZoom: 14.2, initialZoom: 14.2,
), ),
children: [ children: [
TileLayer( const _BaseMapTileLayer(),
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', const _MapAttribution(),
userAgentPackageName: 'com.mapflow.app',
),
], ],
), ),
SafeArea( SafeArea(
@@ -187,6 +182,54 @@ class _MapError extends StatelessWidget {
} }
} }
class _BaseMapTileLayer extends StatelessWidget {
const _BaseMapTileLayer();
static const _osmUrl = 'https://tile.openstreetmap.org/{z}/{x}/{y}.png';
@override
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 {
const _MapAttribution();
@override
Widget build(BuildContext context) {
if (_mapboxAccessToken.isEmpty) {
return const RichAttributionWidget(
attributions: [
TextSourceAttribution('OpenStreetMap contributors'),
],
);
}
return const RichAttributionWidget(
attributions: [
TextSourceAttribution('Mapbox', prependCopyright: false),
TextSourceAttribution('OpenStreetMap contributors'),
],
);
}
}
class _TraitBar extends ConsumerWidget { class _TraitBar extends ConsumerWidget {
const _TraitBar({required this.selectedTrait}); const _TraitBar({required this.selectedTrait});