plug_location_map 1.0.0
plug_location_map: ^1.0.0 copied to clipboard
Plug-and-play Google Maps location package for Flutter. Body-only — host app provides its own AppBar. Handles permissions, GPS, Zomato map picker, Instacart address form, Firebase persistence, offline [...]
example/lib/main.dart
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:permission_handler_package/permission_handler_package.dart';
import 'package:plug_location_map/plug_location_map.dart';
import 'package:riverpod_offline_sync/riverpod_offline_sync.dart';
import 'app_router.dart';
/// ════════════════════════════════════════════════════════════════════════════
/// MAXIMAL EXAMPLE — exercises every feature of plug_location_map.
///
/// • All three required initialisations (permissions, Hive+sync, Firebase)
/// • Every PlugMapConfig flag turned on
/// • Every callback wired with debugPrint
/// • A custom PlugMapTheme override
/// • A serviceabilityChecker implementation
/// • A custom storage prefix + sync config
/// • PlugMapScope wrapping with a userId for Firebase
/// ════════════════════════════════════════════════════════════════════════════
const kGoogleApiKey = 'YOUR_GOOGLE_MAPS_API_KEY';
const kIosApiKey = 'YOUR_IOS_API_KEY';
/// Toggle this to demo Firebase persistence.
const kUseFirebase = false;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
// ── 1. permission_handler_package ^1.0.7 ──────────────────────────────────
await PermissionHandler.initialize();
// ── 2. Firebase (optional) ────────────────────────────────────────────────
if (kUseFirebase) {
await Firebase.initializeApp();
}
// ── 3. riverpod_offline_sync ^1.0.6 ──────────────────────────────────────
await Hive.initFlutter();
await OfflineSyncLayer.instance.initialize(
config: const SyncConfig(
autoSyncOnReconnect: true,
syncImmediately: true,
maxConcurrentOperations: 3,
maxRetries: 5,
),
);
runApp(
ProviderScope(
child: PlugMapScope(
userId: kUseFirebase ? 'demo_user_uid_123' : null,
config: _buildMaximalConfig(),
child: const MaximalApp(),
),
),
);
}
/// Every flag, every callback, a custom theme, serviceability, custom storage.
PlugMapConfig _buildMaximalConfig() {
return PlugMapConfig(
googleApiKey: kGoogleApiKey,
iosApiKey: kIosApiKey,
// Feature flags — all on
enableLiveTracking: true,
enableAddressImage: false,
enableReceiverDetails: true,
enableServiceabilityCheck: true,
enableOfflineSync: true,
enableFirebase: kUseFirebase,
addressTypes: const [
AddressType.home,
AddressType.work,
AddressType.site,
AddressType.other,
],
defaultZoom: 16.0,
countryCode: 'in',
geocodingDebounce: const Duration(milliseconds: 500),
storagePrefix: 'maximal_demo',
syncConfig: const SyncConfig(
autoSyncOnReconnect: true,
syncImmediately: true,
maxConcurrentOperations: 4,
maxRetries: 6,
),
// Serviceability: anything north of lat 30 is "unserviceable".
serviceabilityChecker: (lat, lng) async {
await Future<void>.delayed(const Duration(milliseconds: 300));
return lat < 30.0;
},
theme: const PlugMapTheme(
primaryColor: Color(0xFFFFE000),
onPrimaryColor: Color(0xFF0A0A0A),
successColor: Color(0xFF16A34A),
errorColor: Color(0xFFDC2626),
fieldRadius: 12,
cardRadius: 14,
pillRadius: 24,
btnRadius: 12,
),
onAddressSelected: (address, source) {
debugPrint('onAddressSelected: ${address.name} via $source');
debugPrint(' street=${address.street} city=${address.city} '
'pin=${address.pincode} lat=${address.lat} lng=${address.lng}');
},
onAddressSaved: (a) => debugPrint('onAddressSaved: ${a.id} ${a.name}'),
onAddressUpdated: (a) => debugPrint('onAddressUpdated: ${a.id}'),
onAddressDeleted: (id) => debugPrint('onAddressDeleted: $id'),
onLocationResolved: (l) => debugPrint('onLocationResolved: ${l.lat},${l.lng}'),
onUnserviceable: (l) => debugPrint('onUnserviceable: ${l.city}'),
onPermissionDenied: (r) => debugPrint('onPermissionDenied: $r'),
onTrackingUpdate: (lat, lng, ts) =>
debugPrint('onTrackingUpdate: $lat,$lng @ $ts'),
onError: (e) => debugPrint('onError: $e'),
onSyncSuccess: (a) => debugPrint('onSyncSuccess: ${a.id}'),
onSyncFailed: (a, e) => debugPrint('onSyncFailed: ${a.id} $e'),
);
}
class MaximalApp extends StatelessWidget {
const MaximalApp({super.key});
@override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: const Size(375, 812),
minTextAdapt: true,
builder: (_, __) => MaterialApp.router(
title: 'plug_location_map — Maximal Demo',
debugShowCheckedModeBanner: false,
routerConfig: exampleRouter,
theme: ThemeData(
useMaterial3: true,
scaffoldBackgroundColor: const Color(0xFFFFFFFF),
colorScheme: const ColorScheme.light(
primary: Color(0xFFFFE000),
onPrimary: Color(0xFF0A0A0A),
surface: Color(0xFFFFFFFF),
onSurface: Color(0xFF0A0A0A),
error: Color(0xFFDC2626),
),
textTheme: GoogleFonts.urbanistTextTheme(),
appBarTheme: AppBarTheme(
backgroundColor: const Color(0xFFFFFFFF),
foregroundColor: const Color(0xFF0A0A0A),
elevation: 0,
titleTextStyle: GoogleFonts.urbanist(
fontSize: 18, fontWeight: FontWeight.w700,
color: const Color(0xFF0A0A0A)),
),
),
),
);
}
}