mirror_connect 0.0.1 copy "mirror_connect: ^0.0.1" to clipboard
mirror_connect: ^0.0.1 copied to clipboard

A lightweight Flutter SDK that connects your app to the Magic Mirror real-time infrastructure

example/lib/main.dart

import 'dart:convert';
import 'dart:math' as math;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mirror_connect/mirror_connect.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:pretty_qr_code/pretty_qr_code.dart';


/// The main entry point of the application.
void main() {
  WidgetsFlutterBinding.ensureInitialized();

  // Set up event callbacks

  runApp(const MyApp());
}

/// The root widget of the application.
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Socket Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Socket Demo Product Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String sessionId = "";
  bool isConnected = false;
  List<String> productId = [];
  TextEditingController controller = TextEditingController();

  @override
  void initState() {
    // generates a unique session ID, and then establishes a connection to the server.
    super.initState();
    sessionId = getSessionId();
    connectToServer();
  }

  /// Generates a unique session ID based on the current timestamp and a random number.
  String getSessionId() {
    final random = math.Random();
    final timestamp = DateTime.now().millisecondsSinceEpoch;
    final randomNumber = random.nextInt(999999);
    String currentId = '${timestamp}_$randomNumber';
    return currentId;
  }


  /// Initializes and connects to the WebSocket server using the MagicConnect.
  /// It sets up listeners for connection, incoming messages, and errors.
  void connectToServer() {

    // Initialize the SDK
    MagicConnect.init();



    MagicConnect.onConnect = () {
      print("✅ Connected to Magic Mirror Server");

      MagicConnect.send("joinSession", sessionId);
    };

    MagicConnect.onMessage = (data) {
      if (data is Map && data.containsKey("scannedItem")) {
        //for device is scanned or not


        /*
        IF data["scannedItem"] == sessionId  is true so magic mirror connected with your session id so you can close or Hide the qr dialog
        */
        if (data["scannedItem"] == sessionId) {

          if (mounted) {
            Navigator.pop(context); // Close the QR dialog
            setState(() {
              isConnected = true;
            });
          }
        }


        //device is disconnected
        else if (data["scannedItem"] == "disconnect") {
          setState(() {
            isConnected = false;
          });
        }
      }

    };

    MagicConnect.onError = (error) {
      print("⚠️ Error: $error");
    };


  }



  /// Sends a disconnect message to the server and updates the UI state.
  void disconnectConnection() {
    var disconnect = {
      "sessionId": sessionId,
      "data": {
        "scannedItem": "disconnect",
        "itemType": "try",
        "timestamp": DateTime.now().toIso8601String(),
      }
    };
    MagicConnect.send("scannerData", disconnect);
    MagicConnect.onDisconnect;
    setState(() {
      isConnected = false;
      productId.clear();
    });
  }


  /// Sends product data to the server for the current session.
  sentData(String product){

    var productData = {
      "sessionId": sessionId,
      "data": {
        "scannedItem": product,
        "itemType": "product",
        "timestamp": DateTime.now().toIso8601String(),
      }
    };
    MagicConnect.send("scannerData", productData);
  }



  /// Builds and returns a widget that displays a QR code for the current session.
  /// The QR code contains session and user details for the magic mirror to scan.
  Widget qrWidget() {

    Map<String, String> qrData  = {
      "urlPrefix": "xx_xx",//add url prefix provide by plushvie
      "customerId": "xx_xx_xx",// add customer id provide by plushvie
      "userName": "Avishkar", //add customer name
      "userNumber": "9876543210", //add customer number
      "employeeId":"12",//add JC's name or employee Id
      "branch": "branch name",//Add store branch name here
      "city": "City name",//Add store city name
      "sessionId": sessionId,//here use you session id
      "counterNumber": "1" // number of counter to be used,
    };



    return Material(
      // color: Colors.black.withOpacity(0.8),
      child: Stack(
        children: [
          GestureDetector(
            onTap: () => Navigator.pop(context),
            child: Container(color: Colors.transparent),
          ),
          Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                const Text(
                  "Scan This QR",
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 25,
                  ),
                ),
                const SizedBox(height: 16),
                Container(
                  padding: const EdgeInsets.all(16),
                  decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(12)
                  ),
                  child: PrettyQrView.data(
                    data: jsonEncode(qrData),
                    decoration: const PrettyQrDecoration(
                      shape: PrettyQrSmoothSymbol(
                        color: Colors.black,
                      ),
                    ),
                  ),
                ),
                const SizedBox(height: 24),
                SizedBox(
                  height: 40,
                  child: Padding(
                    padding: const EdgeInsets.symmetric(vertical: 6.0),
                    child: Image.network(
                        "https://plushvie.in/sdk_app/poweredbyplushvie.png"),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
        actions: [
          if (isConnected)
            TextButton(
              onPressed: disconnectConnection,
              child: const Text("Disconnect"),
            )
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            Card(
              elevation: 2,
              child: Padding(
                padding: const EdgeInsets.only(left: 16),
                child: Row(
                  children: [
                    Expanded(
                      child: TextFormField(
                        controller: controller,
                        decoration: const InputDecoration(
                          border: InputBorder.none,
                          hintText: "Enter or scan a product code",
                        ),
                        onFieldSubmitted: (value) {
                          if (value.isNotEmpty) {
                            sentData(value);
                            // sentProductData(value);
                            if (!productId.contains(value)) {
                              setState(() {
                                productId.add(value);
                              });
                            }
                            controller.clear();
                          }
                        },
                      ),
                    ),
                    IconButton(
                      onPressed: () async {
                        final scannerData = await Navigator.push<String>(
                          context,
                          MaterialPageRoute(
                              builder: (context) => const ScannerPage()),
                        );
                        if (scannerData != null && scannerData.isNotEmpty) {
                          setState(() {
                            controller.text = scannerData;
                          });
                        }
                      },
                      icon: const Icon(Icons.camera_alt_outlined),
                      tooltip: "Scan Barcode",
                    ),
                    IconButton(
                      icon: const Icon(CupertinoIcons.arrow_right_circle_fill),
                      onPressed: () {
                        if (controller.text.isEmpty) return;
                        sentData(controller.text);
                        // sentProductData(controller.text);
                        if (!productId.contains(controller.text)) {
                          setState(() {
                            productId.add(controller.text);
                          });
                        }
                        controller.clear();
                      },
                      tooltip: "Send Product",
                    ),
                  ],
                ),
              ),
            ),
            const SizedBox(height: 20),
            Expanded(
              child: productId.isEmpty
                  ? const Center(child: Text("No products sent yet."))
                  : Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const Text("Sent Products:", style: TextStyle(fontWeight: FontWeight.bold)),
                  Expanded(
                    child: ListView(
                      children: [
                        Wrap(
                          spacing: 8.0,
                          runSpacing: 4.0,
                          children:
                          List.generate(productId.length, (int index) {
                            return GestureDetector(
                              onTap: () {
                                setState(() {
                                  controller.text = productId[index];
                                });
                              },
                              child: Chip(
                                label: Text(productId[index]),
                                onDeleted: () {
                                  setState(() {
                                    productId.removeAt(index);
                                  });
                                },
                              ),
                            );
                          }),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          showDialog(
            context: context,
            builder: (context) => qrWidget(),
          );
        },
        tooltip: 'Show Session QR',
        child: const Icon(Icons.qr_code),
      ),
    );
  }

  @override
  /// Disposes of the TextEditingController when the widget is removed from the widget tree.
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}

class ScannerPage extends StatefulWidget {
  const ScannerPage({super.key});

  @override
  State<ScannerPage> createState() => _ScannerPageState();
}

class _ScannerPageState extends State<ScannerPage> {
  final MobileScannerController barcodeController = MobileScannerController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Scan Barcode')),
      body: MobileScanner(
        controller: barcodeController,
        onDetect: (BarcodeCapture capture) {
          final barcode = capture.barcodes.first;
          final code = barcode.rawValue;

          if (code != null) {
            barcodeController.stop();
            Navigator.pop(context, code);
          }
        },
      ),
    );
  }

  @override
  /// Disposes of the MobileScannerController when the widget is removed from the widget tree.
  void dispose() {
    barcodeController.dispose();
    super.dispose();
  }
}




/*needed packages


------------------------------------------------------
For generate qr cod you can use any other package
flutter pub add pretty_qr_code  */
1
likes
150
points
9
downloads

Publisher

verified publisherplushvie.in

Weekly Downloads

A lightweight Flutter SDK that connects your app to the Magic Mirror real-time infrastructure

Homepage

Documentation

API reference

License

unknown (license)

Dependencies

flutter, socket_io_client

More

Packages that depend on mirror_connect