tcmpp_flutter 2.0.3 copy "tcmpp_flutter: ^2.0.3" to clipboard
tcmpp_flutter: ^2.0.3 copied to clipboard

TCMPP Flutter SDK.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:tcmpp_flutter/tcmpp_flutter.dart';
import 'package:tcmpp_flutter_example/appid_dialog.dart';
import 'package:tcmpp_flutter_example/mini_item.dart';
import 'package:tcmpp_flutter_example/search.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    SystemChrome.setPreferredOrientations([
      DeviceOrientation.portraitUp,
    ]);
    return const MaterialApp(home: HomePage());
  }
}

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

  @override
  State<StatefulWidget> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
  final _tcmppFlutterPlugin = TcmppFlutter();
  final List<AppInfo> _appInfoList = [];

  @override
  void initState() {
    super.initState();
    _tcmppFlutterPlugin.registerOpenApiHandler(MyOpenApiHandler());
    _tcmppFlutterPlugin.registerPlatformEventHandler(MyPlatformHandler());
    _tcmppFlutterPlugin.registerMiniAppApi("testState", myApiHandler);
    _tcmppFlutterPlugin.registerMiniAppApi("myRequestPayment", myApiHandler1);
    _tcmppFlutterPlugin.setAccount(AccountInfo(
        uid: "12345",
        avatarUrl: "https://picsum.photos/250?image=9",
        accountName: "SimpleAccount"));
    _tcmppFlutterPlugin.setLocale("en", region: "us");
    _tcmppFlutterPlugin
        .defaultShareTargets([ShareTarget.qq, ShareTarget.wxMoment]);
    WidgetsBinding.instance.addObserver(this);
    if (WidgetsBinding.instance.lifecycleState == AppLifecycleState.resumed) {
      getRecentMini();
    }
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (state == AppLifecycleState.resumed) {
      getRecentMini();
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  Future<void> getRecentMini() async {
    List<AppInfo>? infoList =
        await _tcmppFlutterPlugin.getRecentList().catchError((err) {
      ScaffoldMessenger.of(context)
          .showSnackBar(SnackBar(content: Text(err.toString())));
    });
    setState(() {
      _appInfoList.clear();
      if (infoList != null) {
        _appInfoList.addAll(infoList.take(10));
      }
    });
  }

  Future<void> scanForResult() async {
    String? link = (await _tcmppFlutterPlugin.scan())?.result;
    if (link?.isNotEmpty ?? false) {
      await _tcmppFlutterPlugin
          .startMiniAppWithLink(link!, null)
          .catchError((err) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text(err.toString())));
      });
    }
  }

  Future<void> startMiniById(String? appId) async {
    if (appId?.isNotEmpty ?? false) {
      await _tcmppFlutterPlugin
          .startMiniAppWithId(appId!, null)
          .catchError((err) {
        ScaffoldMessenger.of(context)
            .showSnackBar(SnackBar(content: Text(err.toString())));
      });
    }
  }

  void open() {
    Navigator.push(
      context,
      MaterialPageRoute(builder: (context) => const SearchPage()),
    );
  }

  /// Custom API
  Future<Map<String, dynamic>?> myApiHandler(MiniApiCall call) async {
    print("API : ${call.apiName}");
    print("AppInfo: ${call.appInfo}");
    print("WebView ID: ${call.webViewId}");
    print("params: ${call.params}");

    return {"result": "event over", "method": "testState"};
  }

  Future<Map<String, dynamic>?> myApiHandler1(MiniApiCall call) async {
    print("API : ${call.apiName}");
    print("AppInfo: ${call.appInfo}");
    print("WebView ID: ${call.webViewId}");
    print("params: ${call.params}");

    throw StateError("password error");
  }

  Widget makeRecentItem(AppInfo info) {
    return GestureDetector(
      onTap: () {
        startMiniById(info.appId);
      },
      child: MiniAppItem(info),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('TCMPP Flutter example'),
        bottom: const PreferredSize(
          preferredSize: Size.fromHeight(1),
          child: Divider(
            color: Color(0xFFE1E1E1),
          ),
        ),
        actions: [
          PopupMenuButton(
              color: Colors.white,
              itemBuilder: (context) => <PopupMenuEntry>[
                    PopupMenuItem(
                        padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                        onTap: () {
                          scanForResult();
                        },
                        child: const Row(
                          children: [
                            Icon(Icons.qr_code_scanner, color: Colors.black87),
                            SizedBox(
                              width: 8,
                            ),
                            Text("Scan")
                          ],
                        )),
                    PopupMenuItem(
                        padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                        onTap: () {
                          open();
                        },
                        child: const Row(
                          children: [
                            Icon(Icons.search, color: Colors.black87),
                            SizedBox(
                              width: 8,
                            ),
                            Text("Search")
                          ],
                        )),
                    PopupMenuItem(
                        padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                        onTap: () {
                          showDialog(
                              context: context,
                              builder: (context) => AppIdDialog((value) {
                                    startMiniById(value);
                                  }));
                        },
                        child: const Row(
                          children: [
                            Icon(Icons.grid_view, color: Colors.black87),
                            SizedBox(
                              width: 8,
                            ),
                            Text("AppId")
                          ],
                        )),
                    // PopupMenuItem(
                    //     padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                    //     onTap: () {},
                    //     child: const Row(
                    //       children: [
                    //         Icon(Icons.info_outline, color: Colors.black87),
                    //         SizedBox(
                    //           width: 8,
                    //         ),
                    //         Text("Information")
                    //       ],
                    //     )),
                  ])
        ],
      ),
      body: Center(
          child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Container(
              constraints: const BoxConstraints.expand(height: 300),
              margin: const EdgeInsets.fromLTRB(16, 10, 16, 10),
              child: Material(
                  elevation: 3,
                  child: Container(
                    decoration: BoxDecoration(
                        border: Border.all(
                            color: const Color(0xFFE1E1E1), width: 0.5)),
                    child: GridView.count(
                      crossAxisCount: 4,
                      padding: const EdgeInsets.all(5),
                      physics: const ScrollPhysics(),
                      children: [
                        for (AppInfo info in _appInfoList) makeRecentItem(info)
                      ],
                    ),
                  ))),
          const SizedBox(
            height: 30,
          ),
        ],
      )),
    );
  }
}

class MyOpenApiHandler extends OpenApiHandler {
  @override
  Future<Map<String, dynamic>> getUserProfile(
      AppInfo appInfo, Map<Object?, Object?> params) async {
    print("getUserProfile:$appInfo params:$params");
    Map<String, dynamic> result = {
      "userInfo": {
        "nickName": "xcode",
        "avatarUrl":
            "https://staticintl.cloudcachetci.com/cms/backend-cms/8WGP653_%E5%BC%80%E5%8F%91%E8%80%85%E5%B7%A5%E5%85%B7%E9%80%9A%E7%94%A8.png",
        "gender": 1,
        "country": "China",
        "province": "ChongQing",
        "city": "ChongQing",
      }
    };
    return Future.value(result);
  }

  @override
  Future<Map<String, dynamic>> login(
      AppInfo appInfo, Map<Object?, Object?> params) async {
    // TODO: implement app
    throw UnimplementedError();
  }

  @override
  Future<Map<String, dynamic>> checkSession(
      AppInfo appInfo, Map<Object?, Object?> params) async {
    // TODO: implement checkSession
    throw UnimplementedError();
  }

  @override
  Future<Map<String, dynamic>> getPhoneNumber(
      AppInfo appInfo, Map<Object?, Object?> params) async {
    // TODO: implement getPhoneNumber
    throw UnimplementedError();
  }

  @override
  Future<Map<String, dynamic>> getUserInfo(
      AppInfo appInfo, Map<Object?, Object?> params) async {
    // TODO: implement getUserInfo
    throw UnimplementedError();
  }

  @override
  Future<Map<String, dynamic>> requestPayment(
      AppInfo appInfo, Map<Object?, Object?> params) async {
    throw UnimplementedError();
  }
}

class MyPlatformHandler extends TcmppPlatformEventHandler {
  @override
  Future<List<CustomMenu>> getCustomMenus() async {
    CustomMenu menu1 = CustomMenu(
        '100', 'res/images/mini_app_wechat_friend.png', 'Share To', true,
        shareKey: 'twitter');
    CustomMenu menu2 = CustomMenu(
        '101',
        'https://staticintl.cloudcachetci.com/cms/backend-cms/8WGP653_%E5%BC%80%E5%8F%91%E8%80%85%E5%B7%A5%E5%85%B7%E9%80%9A%E7%94%A8.png',
        'Custom',
        false);

    return [
      menu1,
      menu2,
    ];
  }

  @override
  Future<void> customMenuClick(String menuId, ShareData? shareMenu) async {
    print("click menuId:$menuId shareMenu:$shareMenu");
    throw UnimplementedError();
  }

  @override
  Future<bool> reportEvent(int eventId, String eventName, AppInfo appInfo,
      Map<Object?, Object?> params) async {
    print("reportEvent:$eventName  appinfo:$appInfo params:$params");
    // TODO: implement reportEvent
    return true;
  }

  @override
  Future<void> onMiniProgramStateChange(
      String appId, MiniProgramState state) async {
    print("app state change: appid=$appId, state=$state");
  }
}