go_chat_sdk 1.1.3
go_chat_sdk: ^1.1.3 copied to clipboard
Flutter IM SDK for go-chat / LumenIM. OpenIM-style API with WebSocket messaging, Local-First cache, AES envelopes, and AI streaming. Supports Android, iOS, macOS, Windows, Linux, and Web (in-app WebVi [...]
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:go_chat_sdk/go_chat_sdk.dart';
import 'im_bootstrap.dart';
import 'pages/home_page.dart';
import 'pages/login_page.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const GoChatDemoApp());
}
class GoChatDemoApp extends StatelessWidget {
const GoChatDemoApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GoChat Demo',
navigatorKey: appNavigatorKey,
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF1B6B4A)),
useMaterial3: true,
inputDecorationTheme: const InputDecorationTheme(
border: OutlineInputBorder(),
),
),
home: const _BootstrapPage(),
);
}
}
/// 冷启动:优先用本地缓存 Token 自动登录,仅在无 Token 或已过期时进入登录页。
class _BootstrapPage extends StatefulWidget {
const _BootstrapPage();
@override
State<_BootstrapPage> createState() => _BootstrapPageState();
}
class _BootstrapPageState extends State<_BootstrapPage> {
String _hint = '正在恢复登录…';
String? _error;
bool _busy = true;
@override
void initState() {
super.initState();
_boot();
}
Future<void> _boot() async {
setState(() {
_busy = true;
_error = null;
_hint = '正在恢复登录…';
});
try {
final me = await tryAutoLogin();
if (!mounted) return;
if (me != null) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => HomePage(me: me)),
);
return;
}
// 无缓存,或 Token 已失效被清理
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const LoginPage()),
);
} catch (e) {
// 多为网络抖动:本地 Token 仍在,允许重试,不必重新输密码
GoChatLogger.e('auto login failed: $e');
if (!mounted) return;
setState(() {
_busy = false;
_error = e.toString();
_hint = '自动登录失败';
});
}
}
void _goLogin() {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const LoginPage()),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
if (_busy) ...[
const CircularProgressIndicator(),
const SizedBox(height: 16),
Text(_hint),
] else ...[
Text(_hint, style: Theme.of(context).textTheme.titleMedium),
if (_error != null) ...[
const SizedBox(height: 12),
Text(
_error!,
textAlign: TextAlign.center,
style: TextStyle(
color: Theme.of(context).colorScheme.error,
),
),
],
const SizedBox(height: 20),
FilledButton(onPressed: _boot, child: const Text('重试')),
const SizedBox(height: 8),
TextButton(onPressed: _goLogin, child: const Text('重新登录')),
],
],
),
),
),
);
}
}