An in-app notification center list you can use to notify your users. Allows you to build high quality, flexible notification feeds very quickly.
| Requirement | Reason |
|---|---|
Courier Inbox Provider
|
Needed to link your Courier Inbox to the SDK |
Authentication
|
Needed to view inbox messages that belong to a user. |
If you are using JWT authentication, be sure to enable JWT support on the Courier Inbox Provider here.
The default CourierInbox styles.
CourierInbox(
onMessageClick: (message, index) {
message.isRead ? message.markAsUnread() : message.markAsRead();
},
onActionClick: (action, message, index) {
print(action);
},
)
CourierTheme. Here are the values that will automatically be used by your Theme.
- Button Style =
Theme.of(context).elevatedButtonTheme.style - Loading Indicator Color =
Theme.of(context).primaryColor - Unread Indicator Color =
Theme.of(context).primaryColor - Title Style =
Theme.of(context).textTheme.titleMedium - Body Style =
Theme.of(context).textTheme.bodyMedium - Time Style =
Theme.of(context).textTheme.labelMedium - Empty / Error State Text Style =
Theme.of(context).textTheme.titleMedium - Empty / Error State Button Style =
Theme.of(context).elevatedButtonTheme.style
The styles you can use to quickly customize the CourierInbox.
final theme = CourierInboxTheme(
unreadIndicatorStyle: const CourierInboxUnreadIndicatorStyle(
indicator: CourierInboxUnreadIndicator.dot,
color: Color(0xFF9747FF),
),
loadingIndicatorColor: Color(0xFF9747FF),
tabIndicatorColor: Color(0xFF9747FF),
tabStyle: CourierInboxTabStyle(
selected: CourierInboxTabItemStyle(
font: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.bold,
fontSize: 18,
color: Color(0xFF9747FF),
),
indicator: CourierInboxTabIndicatorStyle(
color: Color(0xFF9747FF),
font: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.normal,
fontSize: 16,
color: Colors.white,
),
),
),
unselected: CourierInboxTabItemStyle(
font: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.normal,
fontSize: 18,
color: Colors.black45,
),
indicator: CourierInboxTabIndicatorStyle(
color: Colors.black45,
font: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.normal,
fontSize: 16,
color: Colors.white,
),
),
),
),
readingSwipeActionStyle: CourierInboxReadingSwipeActionStyle(
read: const CourierInboxSwipeActionStyle(
icon: Icons.drafts,
color: Color(0xFF9747FF),
),
unread: CourierInboxSwipeActionStyle(
icon: Icons.mark_email_read,
color: Color(0xFF9747FF).withOpacity(0.5),
),
),
archivingSwipeActionStyle: const CourierInboxArchivingSwipeActionStyle(
archive: CourierInboxSwipeActionStyle(
icon: Icons.inbox,
color: Colors.red,
),
),
titleStyle: CourierInboxTextStyle(
read: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.normal,
fontSize: 18,
),
unread: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
timeStyle: CourierInboxTextStyle(
read: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.normal,
fontSize: 16,
),
unread: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
bodyStyle: CourierInboxTextStyle(
read: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.normal,
fontSize: 16,
),
unread: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
buttonStyle: CourierInboxButtonStyle(
read: FilledButton.styleFrom(
backgroundColor: Colors.grey,
foregroundColor: Colors.white,
textStyle: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.normal,
fontSize: 16,
),
),
unread: FilledButton.styleFrom(
backgroundColor: Color(0xFF9747FF),
foregroundColor: Colors.white,
textStyle: GoogleFonts.sen().copyWith(
fontWeight: FontWeight.normal,
fontSize: 16,
),
),
),
separator: null,
);
// Pass the theme to the inbox
// This example will use the same theme for light and dark mode
CourierInbox(
canSwipePages: true,
lightTheme: theme,
darkTheme: theme,
scrollController: _customScrollController,
onMessageClick: (message, index) {
message.isRead ? message.markAsUnread() : message.markAsRead();
},
onActionClick: (action, message, index) {
print(action);
},
onMessageLongPress: (message, index) {
print(message);
},
onError: (error) {
print(error);
return 'Your custom error message';
}
)
...
The raw data you can use to build whatever UI you'd like.
late CourierInboxListener _inboxListener;
bool _isLoading = true;
String? _error;
List<InboxMessage> _messages = [];
bool _canLoadMore = false;
_inboxListener = await Courier.shared.addInboxListener(
onLoading: (isRefresh) {
setState(() {
if (!isRefresh) _isLoading = true;
_error = null;
});
},
onError: (error) {
setState(() {
_isLoading = false;
_error = error;
});
},
onUnreadCountChanged: (unreadCount) {
print('unreadCount: $unreadCount');
},
onTotalCountChanged: (feed, totalCount) {
print('totalCount: $totalCount');
},
onMessagesChanged: (messages, canPaginate, feed) {
if (feed == InboxFeed.feed) {
setState(() {
_messages = messages;
_isLoading = false;
_error = null;
_canLoadMore = canPaginate;
});
}
},
onPageAdded: (messages, canPaginate, isFirstPage, feed) {
if (feed == InboxFeed.feed && !isFirstPage) {
setState(() {
_messages = messages;
_isLoading = false;
_error = null;
_canLoadMore = canPaginate;
});
}
},
onMessageEvent: (message, index, feed, event) {
switch (event) {
case InboxMessageEvent.added:
setState(() {
_messages.insert(index, message);
});
break;
case InboxMessageEvent.read:
setState(() {
_messages[index] = message;
});
break;
case InboxMessageEvent.unread:
setState(() {
_messages[index] = message;
});
break;
case InboxMessageEvent.opened:
setState(() {
_messages[index] = message;
});
break;
case InboxMessageEvent.archived:
setState(() {
_messages.removeAt(index);
});
break;
case InboxMessageEvent.clicked:
setState(() {
_messages[index] = message;
});
break;
}
},
);
..
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.separated(
itemCount: _messages.length,
itemBuilder: (BuildContext context, int index) {
final message = _messages[index];
return Text(message.messageId)
},
),
);
}
..
@override
void dispose() {
_inboxListener.remove().catchError((error) {
print('Failed to remove inbox listener: $error');
});
super.dispose();
}
| Link |
|---|
Examples
|
// Pagination
await Courier.shared.setInboxPaginationLimit(limit: 100);
final messages = await Courier.shared.fetchNextInboxPage();
// Currently fetched messages
final messages = await Courier.shared.inboxMessages;
// Pull to refresh
await Courier.shared.refreshInbox();
// Update a message
await Courier.shared.openMessage(messageId: messageId);
await Courier.shared.readMessage(messageId: messageId);
await Courier.shared.unreadMessage(messageId: messageId);
await Courier.shared.clickMessage(messageId: messageId);
await Courier.shared.archiveMessage(messageId: messageId);
await Courier.shared.readAllInboxMessages();
// Update message shortcuts
final message = InboxMessage(...);
await message.markAsOpened();
await message.markAsRead();
await message.markAsUnread();
await message.markAsClicked();
await message.markAsArchived();
// Listener
final inboxListener = await Courier.shared.addInboxListener(
onLoading: (isRefresh) {
},
onError: (error) {
},
onUnreadCountChanged: (unreadCount) {
},
onTotalCountChanged: (feed, totalCount) {
},
onMessagesChanged: (messages, canPaginate, feed) {
},
onPageAdded: (messages, canPaginate, isFirstPage, feed) {
},
onMessageEvent: (message, index, feed, event) {
},
);
await inboxListener.remove();👋 Inbox APIs can be found here