whatsapp_chat_sdk 1.0.1
whatsapp_chat_sdk: ^1.0.1 copied to clipboard
Flutter UI SDK for WhatsApp-style chat — embed chat list, threads, bubbles, emoji & attachments in your app. UI only, no backend.
whatsapp_chat_sdk #
A Flutter UI SDK for building WhatsApp-style chat experiences inside your own app.
It provides ready-made widgets (chat list, thread screen, bubbles, emoji picker, attachments) and optional local state — not a standalone chat app and not a backend.
Repository: github.com/deepakyadav-developer/whatsapp_chat_sdk
Install in your Flutter app (3 steps) #
1. Add to pubspec.yaml:
dependencies:
whatsapp_chat_sdk:
git:
url: https://github.com/deepakyadav-developer/whatsapp_chat_sdk.git
ref: main
After the package is on pub.dev, use this instead (no Git needed):
dependencies: whatsapp_chat_sdk: ^1.0.0
2. Install packages:
flutter pub get
3. Import and use:
import 'package:whatsapp_chat_sdk/whatsapp_chat_sdk.dart';
That’s it — embed WhatsAppChatsPage or WhatsAppChatScreen in your app (see Quick start).
Table of contents #
- What this package is
- Features
- Requirements
- Installation
- Quick start
- How to use in your app
- Widget reference
- Models
- Controller
- Themes
- Attachments & permissions
- Connect your backend
- Demo data
- Example project
- Platform support
- FAQ
- License
What this package is #
| Included | Not included |
|---|---|
| Chat list UI | User authentication |
| Chat thread UI (messages + input) | REST / Firebase / WebSocket server |
| Message bubbles (text, media, contact, etc.) | Push notifications |
| Emoji picker & attachment sheet UI | Message encryption |
| Light / dark themes | Account / contact sync from device |
Optional WhatsAppChatController for local/demo state |
A full clone WhatsApp app shell |
Recommended usage: embed WhatsAppChatsPage and WhatsAppChatScreen in your Scaffold, tabs, or routes.
Optional: WhatsAppChatApp is a pre-built demo shell for prototypes only.
flowchart LR
subgraph your_app [Your Flutter App]
A[Your AppBar / Nav / Auth]
B[WhatsAppChatsPage]
C[WhatsAppChatScreen]
end
subgraph sdk [whatsapp_chat_sdk]
B --> D[WhatsAppChatList]
C --> E[WhatsAppMessageBubble]
C --> F[WhatsAppInputBar]
C --> G[WhatsAppEmojiPicker]
end
subgraph backend [You implement]
H[API / Firebase / Socket]
end
B --> H
C --> H
Features #
- Conversation list — avatars, unread count, last message preview, typing indicator on list
- Chat screen — wallpaper, date dividers, auto-scroll, group sender names
- Message types — text, image, video, audio, document, location, contact, sticker, system
- Read receipts — sending, sent ✓, delivered ✓✓, read (blue ✓✓), failed
- Input bar — emoji picker, attach menu, camera shortcut, send / mic button
- Attachments — document, camera, gallery (photo/video), contact (from chat participants), location (demo picker)
- Voice messages — hold mic to record, release to send; tap play/pause in bubble
- Reply preview — quoted message in composer (wire
replyToon send) - Forwarded label on bubbles
- Themes —
WhatsAppTheme.light()/.dark()or fully custom colors - Controller —
ChangeNotifierfor conversations + messages (swap with your state management later)
Requirements #
- Flutter 3.3+
- Dart 3.11+ (see
pubspec.yamlenvironment.sdk) - Your app must declare platform permissions for camera/gallery/files (see Attachments)
Installation #
| Method | When to use |
|---|---|
| Git | Now — install directly from GitHub (see Install in 3 steps) |
| pub.dev | After dart pub publish — whatsapp_chat_sdk: ^1.0.0 (no git: block) |
| path | You cloned the repo and develop SDK + app side by side |
From GitHub (recommended until pub.dev) #
dependencies:
whatsapp_chat_sdk:
git:
url: https://github.com/deepakyadav-developer/whatsapp_chat_sdk.git
ref: main
flutter pub get
From pub.dev (after publish) #
Remove any git: dependency and use:
dependencies:
whatsapp_chat_sdk: ^1.0.0
flutter pub get
Clone repo (contributors / run example) #
git clone https://github.com/deepakyadav-developer/whatsapp_chat_sdk.git
cd whatsapp_chat_sdk/example
flutter pub get
flutter run
Local path (SDK development) #
dependencies:
whatsapp_chat_sdk:
path: ../whatsapp_chat_sdk
Import:
import 'package:whatsapp_chat_sdk/whatsapp_chat_sdk.dart';
Quick start #
Minimal integration: your MaterialApp, your AppBar, SDK only for the messages body.
import 'package:flutter/material.dart';
import 'package:whatsapp_chat_sdk/whatsapp_chat_sdk.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late final WhatsAppChatController _controller;
@override
void initState() {
super.initState();
_controller = WhatsAppChatController(
currentUserId: 'me',
conversations: [], // load from your API
messagesByChatId: {},
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: const Text('Messages')),
body: WhatsAppChatsPage(
controller: _controller,
currentUserId: 'me',
theme: WhatsAppTheme.light(),
),
),
);
}
}
Run the bundled example:
cd example
flutter run
How to use in your app #
Pattern 1 — Conversation list (recommended) #
Use WhatsAppChatsPage inside any parent widget (Scaffold, TabBarView, Drawer, etc.).
WhatsAppChatsPage(
controller: controller,
currentUserId: currentUserId,
theme: WhatsAppTheme.dark(),
header: MyPromoBanner(), // optional widget above list
emptyWidget: MyEmptyChatsWidget(), // optional
onChatTap: (chat) { // optional — default opens chat screen
WhatsAppChatOpener.open(
context,
conversation: chat,
controller: controller,
currentUserId: currentUserId,
);
},
)
Pattern 2 — Open a chat from a button / notification #
WhatsAppChatOpener.open(
context,
conversation: conversation,
controller: controller,
currentUserId: 'me',
onSend: (text) => myApi.sendText(conversation.id, text),
onSendMessage: (msg) => myApi.sendMessage(conversation.id, msg),
);
Pattern 3 — Chat screen only (you own the list) #
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => WhatsAppChatScreen(
conversation: conversation,
messages: messages,
currentUserId: 'me',
onSend: (text) => sendText(text),
onSendMessage: (msg) => sendFullMessage(msg),
isTyping: remoteUserIsTyping,
typingLabel: 'Alice is typing...',
enableAttachments: true,
),
),
);
Pattern 4 — List widget only (full control) #
WhatsAppChatList(
conversations: chats,
currentUserId: 'me',
theme: theme,
onChatTap: (chat) => /* your navigation */,
)
Pattern 5 — Single bubble (custom layout) #
WhatsAppMessageBubble(
message: message,
isMe: message.senderId == myUserId,
theme: theme,
showSenderName: isGroup,
senderName: 'Alice',
onLongPress: () => showMessageActions(message),
)
Pattern 6 — Demo shell (prototypes only) #
// Includes WhatsApp-style app bar + FAB — not for production branding
WhatsAppChatApp(
currentUserId: 'me',
controller: controller,
title: 'Chats',
)
Widget reference #
| Widget | Purpose |
|---|---|
WhatsAppChatsPage |
Main entry — list + listens to controller + opens chat |
WhatsAppChatScreen |
Full thread: app bar, messages, typing, input, attachments |
WhatsAppChatList |
Conversation list only |
WhatsAppChatOpener |
Static helper to Navigator.push chat screen |
WhatsAppInputBar |
Composer with emoji / attach / send |
WhatsAppEmojiPicker |
Standalone emoji panel |
WhatsAppMessageBubble |
Single message bubble |
WhatsAppChatAppBar |
Thread header (avatar, name, actions) |
WhatsAppAvatar |
Circle avatar with optional online dot |
WhatsAppTypingIndicator |
Animated typing dots |
WhatsAppDateDivider |
“Today”, “Yesterday”, date labels |
WhatsAppWallpaper |
Chat background pattern |
WhatsAppAttachmentSheet |
Attach menu bottom sheet |
WhatsAppContactPickerSheet |
Share contact bottom sheet |
WhatsAppAttachmentHandler |
Pick gallery / camera / file / location |
WhatsAppChatApp |
All-in-one demo shell (optional) |
Models #
ChatUser #
ChatUser(
id: 'user_1',
name: 'Alice',
avatarUrl: 'https://...', // optional
phone: '+1 555-0100', // used when sharing contact
isOnline: true,
)
ChatConversation #
ChatConversation(
id: 'chat_1',
title: 'Alice',
participants: [me, alice],
isGroup: false,
unreadCount: 2,
lastMessage: lastMsg,
isTyping: false,
typingUserName: null,
)
ChatMessage #
ChatMessage(
id: 'm1',
senderId: 'me',
createdAt: DateTime.now(),
type: MessageType.text, // see MessageType enum
text: 'Hello',
status: MessageStatus.sent,
replyTo: quotedMessage,
mediaUrl: '/path/or/https/url', // image, video, local or network
fileName: 'report.pdf',
contactName: 'Bob',
contactPhone: '+1...',
latitude: 37.77,
longitude: -122.42,
)
MessageType #
text · image · video · audio · document · location · contact · sticker · system
MessageStatus #
sending · sent · delivered · read · failed
ChatAttachmentResult #
Returned by pickers; convert to message:
final result = await WhatsAppAttachmentHandler.pickFromGallery();
if (result != null) {
final message = result.toMessage(
id: uuid,
senderId: myUserId,
);
controller.sendChatMessage(chatId: chatId, message: message);
}
Controller #
WhatsAppChatController extends ChangeNotifier. Use with ListenableBuilder, AnimatedBuilder, or your state library.
| Method | Description |
|---|---|
conversations |
Read-only list of chats |
messagesFor(chatId) |
Messages in a thread |
sendMessage(chatId:, text:) |
Send text (demo delivery simulation) |
sendChatMessage(chatId:, message:) |
Send any MessageType |
setConversations(list) |
Replace all chats (e.g. after API fetch) |
setMessages(chatId, list) |
Replace thread messages |
addConversation(chat) |
Add new chat |
updateConversation(chat) |
Update metadata |
markAsRead(chatId) |
Clear unread badge |
setTyping(chatId:, isTyping:, userName:) |
Typing state for list + screen |
Important: sendMessage / sendChatMessage simulate delivery with delays. In production, call setMessages or update status after your API responds.
// Listen to updates
controller.addListener(() => setState(() {}));
// Or
ListenableBuilder(
listenable: controller,
builder: (_, __) => WhatsAppChatsPage(controller: controller, ...),
);
Themes #
// Presets
final light = WhatsAppTheme.light();
final dark = WhatsAppTheme.dark();
// Custom
final brand = WhatsAppTheme(
primaryColor: Color(0xFF075E54),
accentColor: Color(0xFF25D366),
sentBubbleColor: Color(0xFFDCF8C6),
receivedBubbleColor: Colors.white,
isDark: false,
);
Pass theme: to WhatsAppChatsPage, WhatsAppChatScreen, WhatsAppChatList, and bubbles.
Color constants: WhatsAppColors.
Attachments & permissions #
The SDK uses image_picker and file_picker.
Permissions must be added in your app, not in the package.
Android (android/app/src/main/AndroidManifest.xml) #
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
iOS (ios/Runner/Info.plist) #
<key>NSCameraUsageDescription</key>
<string>Used to take photos for chat messages</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Used to pick photos for chat messages</string>
<key>NSMicrophoneUsageDescription</key>
<string>Used to record voice messages</string>
Voice messages (built into WhatsAppChatScreen) #
- Hold the green mic button (when the text field is empty).
- Release to send, or use the recording bar to cancel/send.
- Playback: tap play on the voice bubble.
Requires onVoiceRecorded (wired automatically on WhatsAppChatScreen when enableAttachments: true).
WhatsAppInputBar(
onSend: onSendText,
onVoiceRecorded: (result) {
final msg = result.toMessage(id: uuid, senderId: myUserId);
controller.sendChatMessage(chatId: chatId, message: msg);
},
);
Uses record and audioplayers.
mediaUrl on ChatMessage stores the local .m4a path (upload to your server in production).
Attachment flow (built into WhatsAppChatScreen) #
- User taps attach →
WhatsAppAttachmentSheet(document, camera, gallery, contact, location). - Handler returns
ChatAttachmentResult. - Screen calls
onSendMessagewith aChatMessage.
Override handlers on the screen or use WhatsAppAttachmentHandler directly for custom UX.
Contact picker uses ChatConversation.participants (excluding current user). Add phone on ChatUser for display.
Connect your backend #
The SDK is UI-only. Typical flow:
- Load chats → map API JSON to
List<ChatConversation>→controller.setConversations(...). - Open chat → fetch messages →
controller.setMessages(chatId, list). - Send text → optimistic UI → API → update
MessageStatuson success/failure. - Send media → upload file → set
mediaUrlto CDN URL →sendChatMessage. - Realtime → on socket event,
setMessagesor patch a single message.
Example (pseudo-code):
Future<void> onSendText(String chatId, String text) async {
final tempId = const Uuid().v4();
final optimistic = ChatMessage(
id: tempId,
senderId: myUserId,
text: text,
createdAt: DateTime.now(),
status: MessageStatus.sending,
type: MessageType.text,
);
controller.sendChatMessage(chatId: chatId, message: optimistic);
try {
final saved = await api.postMessage(chatId, text);
final list = controller.messagesFor(chatId).map((m) {
return m.id == tempId
? m.copyWith(id: saved.id, status: MessageStatus.sent)
: m;
}).toList();
controller.setMessages(chatId, list);
} catch (_) {
// mark failed
}
}
Works with Provider, Riverpod, Bloc, GetX, etc. — use the controller as a starting point or bind widgets to your own streams.
Demo data #
For prototyping and the example app:
WhatsAppChatController(
currentUserId: WhatsAppDemoData.currentUserId,
conversations: WhatsAppDemoData.conversations(),
messagesByChatId: WhatsAppDemoData.messagesByChat(),
);
Do not ship demo data in production.
Example project #
Location: example/
Shows embedding the SDK in a host app with:
- Custom
AppBar(“My App — Messages”) - Bottom navigation (Messages / Settings)
WhatsAppChatsPageon the Messages tab- Chat light/dark toggle (SDK theme only)
Platform support #
| Platform | UI | Emoji picker | Gallery / camera | File picker |
|---|---|---|---|---|
| Android | ✅ | ✅ | ✅ (with permissions) | ✅ |
| iOS | ✅ | ✅ | ✅ (with permissions) | ✅ |
| Web | ✅ | ✅ | Limited | ✅ |
| Windows | ✅ | ✅ | ✅ | ✅ |
| macOS | ✅ | ✅ | ✅ | ✅ |
| Linux | ✅ | ✅ | Varies | ✅ |
Local image paths in bubbles use Image.file on IO platforms and network URLs everywhere.
FAQ #
Is this a full WhatsApp app?
No. It is a UI kit you place inside your application.
Can I use only the chat screen?
Yes. Use WhatsAppChatScreen + your own list/navigation.
Does it store messages permanently?
Only in memory via WhatsAppChatController. Persist with your database.
Can I change colors and fonts?
Yes, via WhatsAppTheme (fontFamily, bubble colors, app bar, etc.).
How do I disable attachments?
Set enableAttachments: false on WhatsAppChatScreen / WhatsAppChatsPage.
Git vs pub.dev — which should I use?
- Before publish: use the
git:URL in your app’spubspec.yaml. - After publish: remove
git:and usewhatsapp_chat_sdk: ^1.0.0from pub.dev only.
Package name / trademark
This is an unofficial UI toolkit. Ensure your app name and branding comply with store policies and trademarks.
Automated release (maintainers) #
Push to pub.dev + Git tag from GitHub Actions:
- Add repo secret
PUB_CREDENTIALS(see .github/PUBLISHING.md) - Actions → Release & Publish → Run workflow → choose
patch/minor/major
Version in pubspec.yaml and CHANGELOG.md update automatically, then the package publishes to pub.dev.
License #
MIT — see LICENSE.