im_plugin_tencent_web 0.0.5 copy "im_plugin_tencent_web: ^0.0.5" to clipboard
im_plugin_tencent_web: ^0.0.5 copied to clipboard

Platformweb

A Flutter plugin integrating Tencent IM for web, supporting chat and audio/video calls. Uses UI-free access method, providing ready-to-use APIs. Web-only integration.

example/lib/main.dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

import 'package:im_plugin_tencent_web/im/init.dart';
import 'package:im_plugin_tencent_web/im_plugin_tencent_web.dart';
import 'package:im_plugin_tencent_web/state/im_state.dart';
import 'package:im_plugin_tencent_web/widget/conversation_list.dart';
import 'package:im_plugin_tencent_web/widget/chat.dart';

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

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

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

class _MyAppState extends State<MyApp> {
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  final TextEditingController imSdkAppIdController = TextEditingController();
  final TextEditingController imLoginUserIdController = TextEditingController();
  final TextEditingController imLoginUserSigController = TextEditingController();

  @override
  void initState() {
    super.initState();

    WidgetsBinding.instance.addPostFrameCallback((_) {
      try {
        doImTencentWebPluginInit();
      } catch (_) {
        Future.delayed(Duration(milliseconds: 400), () {
          _scaffoldKey.currentState?.openEndDrawer();
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        key: _scaffoldKey,
        appBar: AppBar(
          title: const Text('腾讯 IM WEB 插件', style: TextStyle(fontSize: 16, color: Colors.white,),),
          backgroundColor: Colors.transparent,
          actions: [
            Builder(
              builder: (context) => Padding(
                padding: EdgeInsets.only(right: 10),
                child: IconButton(
                  icon: Icon(Icons.settings),
                  onPressed: () {
                    Scaffold.of(context).openEndDrawer();
                  },
                ),
              ),
            ),
          ],
        ),
        endDrawer: Builder(builder: (ctx) {
          return Container(
            color: Colors.grey.shade900,
            width: 400,
            height: MediaQuery.of(context).size.height,
            child: SingleChildScrollView(
              padding: EdgeInsets.only(left: 20, right: 20, top: 20, bottom: 20,),
              child: AnimatedBuilder(
                animation: Listenable.merge([
                  ImState.chatInstance,
                  ImState.chatLoginInfo,
                ]),
                builder: (ctx, _) {
                  return Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Text('IM 初始化', style: TextStyle(fontSize: 14, color: Colors.grey.withAlpha(160)),),
                      const SizedBox(height: 5,),
                      Row(
                        children: [
                          Expanded(
                            child: IgnorePointer(
                              ignoring: ImState.chatInstance.value != null,
                              child: Opacity(
                                opacity: ImState.chatInstance.value != null ? 0.2 : 1,
                                child: SizedBox(
                                  height: 40,
                                  child: TextField(
                                    controller: imSdkAppIdController,
                                    style: TextStyle(fontSize: 14, color: Colors.white,),
                                    decoration: InputDecoration(
                                      hintText: '在这里输入 sdkAppID',
                                      hintStyle: TextStyle(fontSize: 14, color: Colors.white.withAlpha(30),),
                                      filled: true,
                                      fillColor: Colors.black87.withAlpha(100),
                                      border: OutlineInputBorder(
                                        borderRadius: BorderRadius.circular(8).copyWith(topRight: Radius.zero, bottomRight: Radius.zero,),
                                        borderSide: BorderSide.none,
                                      ),
                                      contentPadding: const EdgeInsets.symmetric(vertical: 13, horizontal: 12),
                                    ),
                                    keyboardType: TextInputType.number,
                                    autofocus: true,
                                  ),
                                ),
                              ),
                            ),
                          ),
                          IgnorePointer(
                            ignoring: ImState.chatInstance.value != null,
                            child: Opacity(
                              opacity: ImState.chatInstance.value != null ? 0.2 : 1,
                              child: SizedBox(
                                height: 40,
                                child: ElevatedButton(
                                  style: ButtonStyle(
                                    elevation: WidgetStateProperty.all(0),
                                    shadowColor: WidgetStateProperty.all(Colors.transparent),
                                    backgroundColor: WidgetStateProperty.all(Colors.black),
                                    shape: WidgetStateProperty.all(
                                      RoundedRectangleBorder(
                                        borderRadius: BorderRadius.circular(8).copyWith(topLeft: Radius.zero, bottomLeft: Radius.zero,),
                                      ),
                                    ),
                                  ),
                                  onPressed: () {
                                    int? sdkAppId = int.tryParse(imSdkAppIdController.text);
                                    if (sdkAppId == null) {
                                      imSdkAppIdController.text = '';
                                      ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
                                        content: const Text('请输入有效的 sdkAppId'),
                                        duration: Duration(milliseconds: 800),
                                      ));
                                      return;
                                    }
                                    doImTencentWebPluginInit(sdkAppId: sdkAppId);
                                  },
                                  child: Text('初始化腾讯 IM'),
                                ),
                              ),
                            ),
                          ),
                        ],
                      ),
                      const SizedBox(height: 15,),
                      Text('IM 销毁', style: TextStyle(fontSize: 14, color: Colors.grey.withAlpha(160)),),
                      const SizedBox(height: 5,),
                      IgnorePointer(
                        ignoring: ImState.chatInstance.value == null,
                        child: Opacity(
                          opacity: ImState.chatInstance.value == null ? 0.2 : 1,
                          child: SizedBox(
                            width: MediaQuery.of(context).size.width,
                            height: 40,
                            child: ElevatedButton(
                              style: ButtonStyle(
                                elevation: WidgetStateProperty.all(0),
                                shadowColor: WidgetStateProperty.all(Colors.transparent),
                                backgroundColor: WidgetStateProperty.all(Colors.redAccent),
                                foregroundColor: WidgetStateProperty.all(Colors.white),
                                shape: WidgetStateProperty.all(
                                  RoundedRectangleBorder(
                                    borderRadius: BorderRadius.circular(8),
                                  ),
                                ),
                              ),
                              onPressed: () async {
                                try {
                                  await ImPluginTencentWeb.destroy();
                                  if (ctx.mounted) {
                                    ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
                                      content: Text('销毁成功'),
                                      duration: Duration(milliseconds: 800),
                                    ));
                                  }
                                } catch(err) {
                                  if (kDebugMode) {
                                    print('销毁出错:$err');
                                  }
                                  if (ctx.mounted) {
                                    ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
                                      content: Text('销毁出错:$err'),
                                      duration: Duration(milliseconds: 800),
                                    ));
                                  }
                                }
                              },
                              child: Text('销毁腾讯 IM'),
                            ),
                          ),
                        ),
                      ),
                      const SizedBox(height: 15,),
                      Text('登录 / 登出 IM 账号', style: TextStyle(fontSize: 14, color: Colors.grey.withAlpha(160)),),
                      const SizedBox(height: 5,),
                      Container(
                        width: MediaQuery.of(context).size.width,
                        decoration: BoxDecoration(
                          color: Colors.black87.withAlpha(40),
                          borderRadius: BorderRadius.circular(8),
                        ),
                        padding: EdgeInsets.all(10),
                        child: Column(
                          children: [
                            IgnorePointer(
                              ignoring: ImState.chatInstance.value == null || ImState.chatLoginInfo.value != null,
                              child: Opacity(
                                opacity: ImState.chatInstance.value == null || ImState.chatLoginInfo.value != null ? 0.2 : 1,
                                child: Row(
                                  children: [
                                    Container(
                                      width: 50,
                                      height: 40,
                                      decoration: BoxDecoration(
                                        color: Colors.black87.withAlpha(80),
                                        borderRadius: BorderRadius.circular(8).copyWith(topRight: Radius.zero, bottomRight: Radius.zero,),
                                      ),
                                      padding: EdgeInsets.only(left: 6),
                                      child: Center(
                                        child: Icon(Icons.account_circle_sharp, color: Colors.grey.withAlpha(60),),
                                      ),
                                    ),
                                    Expanded(child: SizedBox(
                                      height: 40,
                                      child: TextField(
                                        controller: imLoginUserIdController,
                                        style: TextStyle(fontSize: 14, color: Colors.white,),
                                        decoration: InputDecoration(
                                          hintText: '输入 userID',
                                          hintStyle: TextStyle(fontSize: 14, color: Colors.white.withAlpha(30),),
                                          filled: true,
                                          fillColor: Colors.black87.withAlpha(100),
                                          border: OutlineInputBorder(
                                            borderRadius: BorderRadius.circular(8).copyWith(topLeft: Radius.zero, bottomLeft: Radius.zero,),
                                            borderSide: BorderSide.none,
                                          ),
                                          contentPadding: const EdgeInsets.symmetric(vertical: 13, horizontal: 10),
                                        ),
                                        keyboardType: TextInputType.number,
                                        autofocus: true,
                                      ),
                                    ),),
                                  ],
                                ),
                              ),
                            ),
                            const SizedBox(height: 5,),
                            IgnorePointer(
                              ignoring: ImState.chatInstance.value == null || ImState.chatLoginInfo.value != null,
                              child: Opacity(
                                opacity: ImState.chatInstance.value == null || ImState.chatLoginInfo.value != null ? 0.2 : 1,
                                child: Row(
                                  children: [
                                    Container(
                                      width: 50,
                                      height: 40,
                                      decoration: BoxDecoration(
                                        color: Colors.black87.withAlpha(80),
                                        borderRadius: BorderRadius.circular(8).copyWith(topRight: Radius.zero, bottomRight: Radius.zero,),
                                      ),
                                      padding: EdgeInsets.only(left: 6),
                                      child: Center(
                                        child: Icon(Icons.signpost_sharp, color: Colors.grey.withAlpha(60),),
                                      ),
                                    ),
                                    Expanded(child: SizedBox(
                                      height: 40,
                                      child: TextField(
                                        controller: imLoginUserSigController,
                                        style: TextStyle(fontSize: 14, color: Colors.white,),
                                        decoration: InputDecoration(
                                          hintText: '输入 userSig',
                                          hintStyle: TextStyle(fontSize: 14, color: Colors.white.withAlpha(30),),
                                          filled: true,
                                          fillColor: Colors.black87.withAlpha(100),
                                          border: OutlineInputBorder(
                                            borderRadius: BorderRadius.circular(8).copyWith(topLeft: Radius.zero, bottomLeft: Radius.zero,),
                                            borderSide: BorderSide.none,
                                          ),
                                          contentPadding: const EdgeInsets.symmetric(vertical: 13, horizontal: 10),
                                        ),
                                        keyboardType: TextInputType.number,
                                        autofocus: true,
                                      ),
                                    ),),
                                  ],
                                ),
                              ),
                            ),
                            const SizedBox(height: 20,),
                            IgnorePointer(
                              ignoring: ImState.chatInstance.value == null,
                              child: Opacity(
                                opacity: ImState.chatInstance.value == null ? 0.2 : 1,
                                child: Builder(builder: (ctx) {
                                  if (ImState.chatLoginInfo.value == null) {
                                    return SizedBox(
                                      width: MediaQuery.of(context).size.width,
                                      height: 40,
                                      child: ElevatedButton(
                                        style: ButtonStyle(
                                          elevation: WidgetStateProperty.all(0),
                                          shadowColor: WidgetStateProperty.all(Colors.transparent),
                                          backgroundColor: WidgetStateProperty.all(Colors.black),
                                          shape: WidgetStateProperty.all(
                                            RoundedRectangleBorder(
                                              borderRadius: BorderRadius.circular(8),
                                            ),
                                          ),
                                        ),
                                        onPressed: () async {
                                          if (imLoginUserIdController.text.trim() == '') {
                                            ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
                                              content: const Text('请输入 userID'),
                                              duration: Duration(milliseconds: 800),
                                            ));
                                            return;
                                          }
                                          if (imLoginUserSigController.text.trim() == '') {
                                            ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
                                              content: const Text('请输入 userSig'),
                                              duration: Duration(milliseconds: 800),
                                            ));
                                            return;
                                          }
                                          try {
                                            doImTencentWebPluginInit(userId: imLoginUserIdController.text.trim(), userSig: imLoginUserSigController.text.trim());
                                          } catch(err) {
                                            if (kDebugMode) {
                                              print('登录出错:$err');
                                            }
                                            if (ctx.mounted) {
                                              ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
                                                content: Text('登录出错:$err'),
                                                duration: Duration(milliseconds: 800),
                                              ));
                                            }
                                          }
                                        },
                                        child: Text('登录腾讯 IM 账号'),
                                      ),
                                    );
                                  }

                                  return SizedBox(
                                    width: MediaQuery.of(context).size.width,
                                    height: 40,
                                    child: ElevatedButton(
                                      style: ButtonStyle(
                                        elevation: WidgetStateProperty.all(0),
                                        shadowColor: WidgetStateProperty.all(Colors.transparent),
                                        backgroundColor: WidgetStateProperty.all(Colors.redAccent),
                                        foregroundColor: WidgetStateProperty.all(Colors.white),
                                        shape: WidgetStateProperty.all(
                                          RoundedRectangleBorder(
                                            borderRadius: BorderRadius.circular(8),
                                          ),
                                        ),
                                      ),
                                      onPressed: () async {
                                        try {
                                          await ImPluginTencentWeb.logout();
                                        } catch(err) {
                                          if (kDebugMode) {
                                            print('登出出错:$err');
                                          }
                                          if (ctx.mounted) {
                                            ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
                                              content: Text('登出出错:$err'),
                                              duration: Duration(milliseconds: 800),
                                            ));
                                          }
                                        }
                                      },
                                      child: Text('登出腾讯 IM 账号'),
                                    ),
                                  );
                                }),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ],
                  );
                },
              ),
            ),
          );
        }),
        backgroundColor: Colors.black87,
        body: Builder(builder: (ctx) {
          return Center(
            child: OverflowBox(
              minWidth: 1000,
              maxWidth: double.infinity,
              minHeight: 600,
              maxHeight: double.infinity,
              child: ValueListenableBuilder(
                valueListenable: ImState.chatLoginInfo,
                builder: (ctx, chatLoginInfo, _) {
                  if (chatLoginInfo == null) {
                    return Container(
                      width: MediaQuery.of(context).size.width * 0.9,
                      height: MediaQuery.of(context).size.height * 0.88,
                      alignment: Alignment(0, -0.26),
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          Icon(Icons.message, size: 60, color: Colors.grey.shade600,),
                          const SizedBox(height: 10,),
                          Text('等待 IM 登录', style: TextStyle(fontSize: 13, color: Colors.grey.shade600,),),
                          Text('点击右上角的 ⚙ 进行登录', style: TextStyle(fontSize: 12, color: Colors.grey.shade600,),),
                        ],
                      ),
                    );
                  }
                  return Container(
                    width: MediaQuery.of(context).size.width * 0.9,
                    height: MediaQuery.of(context).size.height * 0.88,
                    clipBehavior: Clip.antiAlias,
                    decoration: BoxDecoration(
                      color: Colors.white,
                      borderRadius: BorderRadius.circular(10),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.black,
                          blurRadius: 10,
                        ),
                      ],
                    ),
                    child: Row(
                      children: [
                        SizedBox(
                          width: 280,
                          child: ConversationListWidget(),
                        ),
                        VerticalDivider(
                          width: 0.1,
                          color: Colors.black87.withAlpha(20),
                        ),
                        Expanded(
                          child: ChatWidget(),
                        ),
                      ],
                    ),
                  );
                },
              ),
            ),
          );
        }),
      ),
    );
  }
}
1
likes
150
points
103
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin integrating Tencent IM for web, supporting chat and audio/video calls. Uses UI-free access method, providing ready-to-use APIs. Web-only integration.

Repository

License

MIT (license)

Dependencies

flutter, flutter_web_plugins, meta, plugin_platform_interface, scrollview_observer, web

More

Packages that depend on im_plugin_tencent_web

Packages that implement im_plugin_tencent_web