supabase_chat_ui 0.1.0
supabase_chat_ui: ^0.1.0 copied to clipboard
Pre-built Flutter UI components for Supabase Chat SDK with customizable themes, screens, and widgets.
/// Minimal example demonstrating supabase_chat_ui usage.
///
/// This example shows:
/// - Using ChatThemeProvider for theming
/// - Pre-built ChatChannelListScreen
/// - Pre-built ChatScreen
/// - Customizing widgets with builders
///
/// For a complete showcase, see the root example/ app.
library;
import 'package:flutter/material.dart';
import 'package:supabase_chat_sdk/supabase_chat_sdk.dart';
import 'package:supabase_chat_ui/supabase_chat_ui.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Initialize the Chat SDK
await ChatClient.instance.initialize(
supabaseUrl: 'YOUR_SUPABASE_URL',
supabaseAnonKey: 'YOUR_SUPABASE_ANON_KEY',
powerSyncUrl: 'YOUR_POWERSYNC_URL',
);
runApp(const UIExampleApp());
}
class UIExampleApp extends StatefulWidget {
const UIExampleApp({super.key});
@override
State<UIExampleApp> createState() => _UIExampleAppState();
}
class _UIExampleAppState extends State<UIExampleApp> {
bool _isDark = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Chat UI Example',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF6366F1),
brightness: _isDark ? Brightness.dark : Brightness.light,
),
useMaterial3: true,
),
// Wrap your app with ChatThemeProvider
builder: (context, child) {
return ChatThemeProvider(
theme: _isDark ? ChatTheme.dark() : ChatTheme.light(),
child: child!,
);
},
home: ChatUIExample(
onToggleTheme: () => setState(() => _isDark = !_isDark),
),
);
}
}
class ChatUIExample extends StatefulWidget {
final VoidCallback onToggleTheme;
const ChatUIExample({super.key, required this.onToggleTheme});
@override
State<ChatUIExample> createState() => _ChatUIExampleState();
}
class _ChatUIExampleState extends State<ChatUIExample> {
final _client = ChatClient.instance;
bool _isConnected = false;
@override
void initState() {
super.initState();
_checkConnection();
}
Future<void> _checkConnection() async {
if (_client.supabase.auth.currentUser != null) {
await _client.connectUser();
setState(() => _isConnected = true);
}
}
@override
Widget build(BuildContext context) {
if (!_isConnected) {
return Scaffold(
appBar: AppBar(
title: const Text('UI Kit Example'),
actions: [
IconButton(
icon: const Icon(Icons.brightness_6),
onPressed: widget.onToggleTheme,
),
],
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Sign in to continue'),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _signIn,
child: const Text('Sign In'),
),
],
),
),
);
}
// Use pre-built ChatChannelListScreen
return ChatChannelListScreen(
title: 'Chats',
onChannelTap: _openChat,
floatingActionButton: FloatingActionButton(
onPressed: _createChannel,
child: const Icon(Icons.add),
),
);
}
Future<void> _signIn() async {
try {
await _client.supabase.auth.signInWithPassword(
email: 'test@example.com',
password: 'password123',
);
await _client.connectUser();
setState(() => _isConnected = true);
} catch (e) {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Sign in failed: $e')),
);
}
}
}
void _openChat(Channel channel) {
Navigator.push(
context,
MaterialPageRoute(
// Use pre-built ChatScreen
builder: (context) => ChatScreen(channel: channel),
),
);
}
Future<void> _createChannel() async {
final name = await showDialog<String>(
context: context,
builder: (context) => AlertDialog(
title: const Text('New Channel'),
content: TextField(
autofocus: true,
decoration: const InputDecoration(labelText: 'Channel name'),
onSubmitted: (value) => Navigator.pop(context, value),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('Cancel'),
),
],
),
);
if (name != null && name.isNotEmpty) {
await _client.channels.createChannel(
type: ChannelType.group,
memberIds: [],
name: name,
);
}
}
}