plug_location_map 1.0.1 copy "plug_location_map: ^1.0.1" to clipboard
plug_location_map: ^1.0.1 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:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:plug_location_map/plug_location_map.dart';

/// ─────────────────────────────────────────────────────────────────────────
/// The ENTIRE host-side surface. Two package widgets, nothing else:
///   1. PlugLocationApp        — wraps the app, inits everything
///   2. PlugHomeWrapper        — body of your home page (automatic flow)
///   + PlugChooseAddressButton — opens Choose Address on tap
/// ─────────────────────────────────────────────────────────────────────────

// TODO: put your real keys + the signed-in user's id here.
const kGoogleApiKey = 'YOUR_ANDROID_API_KEY';
const kIosApiKey = 'YOUR_IOS_API_KEY';
const kUserId = 'demo-user-123';

void main() {
  runApp(
    // ① One wrapper. Handles Riverpod (auto-guard), permissions, Hive,
    //    offline sync, Firebase. You just pass keys + userId + theme.
    PlugLocationApp(
      config: PlugMapConfig(
        googleApiKey: kGoogleApiKey,
        iosApiKey: kIosApiKey,
        enableFirebase: true,
        userId: kUserId,
        firebaseCollection: 'addresses',
        // Your theme — everything in the package picks this up.
        theme: const PlugMapTheme(
          primaryColor: Color(0xFFFFE000),
          onPrimaryColor: Color(0xFF0A0A0A),
          successColor: Color(0xFF16A34A),
        ),
      ),
      child: const MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'plug_location_map demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(useMaterial3: true),
      home: const HomePage(), // use go_router or anything — doesn't matter
    );
  }
}

/// Your home page. You build the AppBar; the package fills the body and runs
/// the whole location flow automatically.
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // ── YOUR styled AppBar ────────────────────────────────────────────────
      appBar: AppBar(
        backgroundColor: const Color(0xFFFFE000),
        elevation: 0,
        title: Text('My Store',
            style: GoogleFonts.urbanist(
                fontWeight: FontWeight.w800, color: const Color(0xFF0A0A0A))),
        actions: const [
          Padding(
            padding: EdgeInsets.only(right: 12),
            // ③ Tap → Choose Address flow (pick / edit / delete / add). Automatic.
            child: Center(child: PlugChooseAddressButton()),
          ),
        ],
      ),

      // ② The flow gate. No address → Select Location (no back arrow);
      //    address exists → your home content below.
      body: PlugHomeWrapper(
        homeBuilder: (context, address) => _HomeContent(address: address),
      ),
    );
  }
}

/// Your actual home content. Read the address straight off the param, or
/// anywhere else with `ref.watch(plugSelectedAddressProvider)`.
class _HomeContent extends ConsumerWidget {
  const _HomeContent({this.address});
  final PlugAddress? address;

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // Either source works — they're the same address.
    final a = address ?? ref.watch(plugSelectedAddressProvider);

    return Padding(
      padding: const EdgeInsets.all(20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text('Delivering to',
              style: GoogleFonts.urbanist(
                  fontSize: 12,
                  fontWeight: FontWeight.w700,
                  color: Colors.black54)),
          const SizedBox(height: 4),
          Text(a?.shortTitle ?? '—',
              style: GoogleFonts.urbanist(
                  fontSize: 20, fontWeight: FontWeight.w800)),
          const SizedBox(height: 2),
          Text(a?.fullAddress ?? '',
              style: GoogleFonts.urbanist(fontSize: 14, color: Colors.black54)),
          const SizedBox(height: 24),

          // Dot-notation access to everything:
          _kv('name', a?.name),
          _kv('street', a?.street),
          _kv('city', a?.city),
          _kv('pincode', a?.pincode),
          _kv('lat', a?.lat.toString()),
          _kv('lng', a?.lng.toString()),
          _kv('type', a?.type.label),
          _kv('synced', a?.isSynced.toString()),

          const Spacer(),
          SizedBox(
            width: double.infinity,
            child: ElevatedButton(
              onPressed: () => PlugFlow.openChooseAddress(context),
              style: ElevatedButton.styleFrom(
                backgroundColor: const Color(0xFFFFE000),
                foregroundColor: const Color(0xFF0A0A0A),
                padding: const EdgeInsets.symmetric(vertical: 16),
              ),
              child: Text('Change / manage addresses',
                  style: GoogleFonts.urbanist(fontWeight: FontWeight.w800)),
            ),
          ),
        ],
      ),
    );
  }

  Widget _kv(String k, String? v) => Padding(
        padding: const EdgeInsets.symmetric(vertical: 3),
        child: Row(
          children: [
            SizedBox(
                width: 80,
                child: Text(k,
                    style: GoogleFonts.robotoMono(
                        fontSize: 12, color: Colors.black45))),
            Expanded(
                child: Text(v ?? '—',
                    style: GoogleFonts.robotoMono(fontSize: 12))),
          ],
        ),
      );
}
0
likes
140
points
109
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

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 sync, and live tracking. Powered by Riverpod · permission_handler_package · riverpod_offline_sync.

Homepage

License

MIT (license)

Dependencies

cloud_firestore, connectivity_plus, equatable, firebase_core, flutter, flutter_animate, flutter_riverpod, flutter_screenutil, geocoding, geolocator, go_router, google_fonts, google_maps_flutter, hive_flutter, http, permission_handler_package, riverpod_offline_sync, shared_preferences, uuid

More

Packages that depend on plug_location_map