zenrtc_sdk 1.0.1
zenrtc_sdk: ^1.0.1 copied to clipboard
Flutter SDK for building one-to-one calls, group calls, meetings, contacts, and user management with ZenRTC.
import 'package:flutter/material.dart';
import 'package:overlay_support/overlay_support.dart';
import 'package:zenrtc_sdk/zenrtc_sdk.dart';
final navigatorKey = GlobalKey<NavigatorState>();
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await ZenRtcSocket.instance.ensureInitialized(
accountId: "0000000000000e59",
projectId: "00000000000ab4a1",
apiKey: "601854e01cc07cced4589eff4ffe4276",
apiSecret:
"830047425cd8bc3a2a1681cd9299b49d64f50b574537ad39545994f98039ebb3",
testMode: true,
navigatorKey: navigatorKey,
);
runApp(const DemoApp());
}
class DemoApp extends StatelessWidget {
const DemoApp({super.key});
@override
Widget build(BuildContext context) {
final seed = const Color(0xFF3D5AFE);
return OverlaySupport.global(
child: MaterialApp(
navigatorKey: navigatorKey,
title: 'Flutter RTC UI Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
useMaterial3: true,
scaffoldBackgroundColor: const Color(0xFFF5F6FB),
colorScheme: ColorScheme.fromSeed(
seedColor: seed,
primary: seed,
secondary: const Color(0xFF00BFA5),
),
appBarTheme: const AppBarTheme(
elevation: 0,
centerTitle: true,
backgroundColor: Colors.transparent,
foregroundColor: Colors.black87,
),
filledButtonTheme: FilledButtonThemeData(
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 14),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
),
textStyle: const TextStyle(
fontWeight: FontWeight.w600,
fontSize: 14,
),
),
),
cardTheme: CardThemeData(
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
),
builder: (context, child) {
return ZenRtcAppShell(child: child ?? const SizedBox.shrink());
},
home: const HomeScreen(),
),
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
static const _users = [
(
id: "user_1",
peer: "user_2",
color: Color(0xFF3D5AFE),
icon: Icons.person,
),
(
id: "user_2",
peer: "user_1",
color: Color(0xFF00BFA5),
icon: Icons.person_outline,
),
(
id: "user_3",
peer: "user_1",
color: Color(0xFFFF6D00),
icon: Icons.person_2_outlined,
),
];
Future<void> _connectAs(BuildContext context, String userId) async {
await ZenRtcSocket.instance.setIdentity(
UserIdentityModel(userId: userId, deviceId: "device_1"),
);
await ZenRtcSocket.instance.connect();
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Connected as $userId"),
behavior: SnackBarBehavior.floating,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
);
}
}
Widget _sectionTitle(String text) {
return Padding(
padding: const EdgeInsets.fromLTRB(20, 24, 20, 10),
child: Text(
text,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w700,
color: Colors.black54,
letterSpacing: 0.3,
),
),
);
}
Widget _userCard(
BuildContext context, {
required String userId,
required String peerId,
required Color color,
required IconData icon,
}) {
return Card(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(18),
child: Row(
children: [
CircleAvatar(
radius: 26,
backgroundColor: color.withOpacity(0.12),
child: Icon(icon, color: color, size: 26),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
userId,
style: const TextStyle(
fontSize: 17,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 2),
Text(
"Peer: $peerId",
style: const TextStyle(fontSize: 13, color: Colors.black45),
),
],
),
),
FilledButton.icon(
style: FilledButton.styleFrom(backgroundColor: color),
onPressed: () => _connectAs(context, userId),
icon: const Icon(Icons.wifi_tethering, size: 18),
label: const Text("Connect"),
),
],
),
),
);
}
Widget _dashboardCard(BuildContext context) {
return Card(
color: Colors.white,
child: Padding(
padding: const EdgeInsets.all(18),
child: Row(
children: [
CircleAvatar(
radius: 26,
backgroundColor: Colors.deepPurple.withOpacity(0.12),
child: const Icon(
Icons.dashboard_rounded,
color: Colors.deepPurple,
size: 26,
),
),
const SizedBox(width: 16),
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Dashboard",
style: TextStyle(fontSize: 17, fontWeight: FontWeight.bold),
),
SizedBox(height: 2),
Text(
"Connect as user_1, then open dashboard",
style: TextStyle(fontSize: 13, color: Colors.black45),
),
],
),
),
FilledButton.icon(
style: FilledButton.styleFrom(backgroundColor: Colors.deepPurple),
onPressed: () =>
ZenRtcHelper.pushDashboardScreen(context: context),
icon: const Icon(Icons.open_in_new, size: 18),
label: const Text("Open"),
),
],
),
),
);
}
Widget _actionChip({
required BuildContext context,
required String label,
required IconData icon,
required Color color,
required VoidCallback onTap,
}) {
return InkWell(
borderRadius: BorderRadius.circular(16),
onTap: onTap,
child: Container(
width: 150,
padding: const EdgeInsets.symmetric(vertical: 18, horizontal: 12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: color.withOpacity(0.25)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.03),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
children: [
CircleAvatar(
radius: 22,
backgroundColor: color.withOpacity(0.12),
child: Icon(icon, color: color),
),
const SizedBox(height: 10),
Text(
label,
textAlign: TextAlign.center,
style: const TextStyle(fontWeight: FontWeight.w600, fontSize: 13),
),
],
),
),
);
}
@override
Widget build(BuildContext context) {
final crudClient = ZenRtcCrudClient(
accountId: "0000000000000e59",
projectId: "00000000000ab4a1",
apiKey: "601854e01cc07cced4589eff4ffe4276",
apiSecret:
"830047425cd8bc3a2a1681cd9299b49d64f50b574537ad39545994f98039ebb3",
testMode: true,
);
return Scaffold(
appBar: AppBar(
title: const Text(
"Flutter RTC UI Demo",
style: TextStyle(fontWeight: FontWeight.w700),
),
),
body: SafeArea(
child: ListView(
padding: const EdgeInsets.only(bottom: 32),
children: [
// Hero header
Container(
margin: const EdgeInsets.fromLTRB(20, 8, 20, 0),
padding: const EdgeInsets.all(22),
decoration: BoxDecoration(
gradient: const LinearGradient(
colors: [Color(0xFF3D5AFE), Color(0xFF00BFA5)],
begin: Alignment.topLeft,
end: Alignment.bottomRight,
),
borderRadius: BorderRadius.circular(22),
boxShadow: [
BoxShadow(
color: const Color(0xFF3D5AFE).withOpacity(0.25),
blurRadius: 20,
offset: const Offset(0, 8),
),
],
),
child: const Row(
children: [
Icon(Icons.rtt, color: Colors.white, size: 34),
SizedBox(width: 14),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Zen RTC Demo",
style: TextStyle(
color: Colors.white,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
SizedBox(height: 4),
Text(
"Connect users, manage contacts & meetings",
style: TextStyle(color: Colors.white70, fontSize: 13),
),
],
),
),
],
),
),
_sectionTitle("Demo Users"),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Column(
children: [
for (final u in _users) ...[
_userCard(
context,
userId: u.id,
peerId: u.peer,
color: u.color,
icon: u.icon,
),
const SizedBox(height: 12),
],
],
),
),
_sectionTitle("Dashboard"),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: _dashboardCard(context),
),
_sectionTitle("Quick Actions"),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: Wrap(
spacing: 12,
runSpacing: 12,
children: [
_actionChip(
context: context,
label: "Create Meeting",
icon: Icons.video_call_rounded,
color: const Color(0xFF3D5AFE),
onTap: () =>
ZenRtcHelper.pushCreateMeetingsScreen(context: context),
),
_actionChip(
context: context,
label: "My Meetings",
icon: Icons.calendar_month_rounded,
color: const Color(0xFF00BFA5),
onTap: () =>
ZenRtcHelper.pushMyMeetingsScreen(context: context),
),
_actionChip(
context: context,
label: "My Contacts",
icon: Icons.contacts_rounded,
color: const Color(0xFFFF6D00),
onTap: () =>
ZenRtcHelper.pushMyContactsScreen(context: context),
),
_actionChip(
context: context,
label: "My Profile",
icon: Icons.account_circle_rounded,
color: const Color(0xFF6200EA),
onTap: () =>
ZenRtcHelper.pushMyProfileScreen(context: context),
),
_actionChip(
context: context,
label: "Create User",
icon: Icons.person_add_alt_1_rounded,
color: const Color(0xFFD500F9),
onTap: () => ZenRtcHelper.showUserBottomSheet(
context: context,
crudClient: crudClient,
),
),
_actionChip(
context: context,
label: "Register Device",
icon: Icons.phonelink_setup_rounded,
color: const Color(0xFF00B8D4),
onTap: () => ZenRtcHelper.showRegisterDeviceBottomSheet(
context: context,
crudClient: crudClient,
),
),
_actionChip(
context: context,
label: "User Screen",
icon: Icons.badge_rounded,
color: const Color(0xFF2962FF),
onTap: () => ZenRtcHelper.showUserScreen(
context: context,
crudClient: crudClient,
),
),
_actionChip(
context: context,
label: "Device Screen",
icon: Icons.devices_rounded,
color: const Color(0xFF00695C),
onTap: () => ZenRtcHelper.showRegisterDeviceScreen(
context: context,
crudClient: crudClient,
),
),
_actionChip(
context: context,
label: "Bulk Users",
icon: Icons.groups_rounded,
color: const Color(0xFFAA00FF),
onTap: () async {
final result = await crudClient.createUsers([
ZenRtcUser(userId: "user_100", displayName: "User 100"),
ZenRtcUser(userId: "user_101", displayName: "User 101"),
ZenRtcUser(userId: "user_102", displayName: "User 102"),
ZenRtcUser(userId: "user_103", displayName: "User 103"),
ZenRtcUser(userId: "user_104", displayName: "User 104"),
]);
debugPrint(result.raw.toString());
},
),
_actionChip(
context: context,
label: "Bulk Contacts",
icon: Icons.import_contacts_rounded,
color: const Color(0xFFC51162),
onTap: () async {
final result = await crudClient.createContacts(
userId: "user_1",
contacts: [
ZenRtcContact(
contactUserId: "user_100",
displayName: "User 100",
nickName: "Office",
description: "Imported Contact",
emails: ["user100@test.com"],
phones: ["+919999999900"],
),
ZenRtcContact(
contactUserId: "user_101",
displayName: "User 101",
nickName: "Friend",
description: '',
emails: [],
phones: [],
),
],
);
debugPrint(result.raw.toString());
},
),
],
),
),
],
),
),
);
}
}