Reminder items can only be issued by the server, and clients are mainly responsible for receiving, displaying, and managing reminder status
Get Reminder Items
Get reminder items for a specific channel
Copy
// Get reminder items for a specific channel
// channelId: Channel ID
// channelType: Channel type
// done: 1.Completed reminder items 0.Incomplete reminder items
WKIM.shared.reminderManager().get(channelId, channelType, done);
Complete reminder item retrieval example
Copy
import { WKIM, WKReminder, WKChannelType } from '@wukong/wkim';
class ReminderManager {
// Get reminder items for a specific channel
static getChannelReminders(channelId: string, channelType: number, done: number = 0): WKReminder[] {
try {
const reminders = WKIM.shared.reminderManager().get(channelId, channelType, done);
console.log(`Retrieved ${reminders.length} reminder items`);
return reminders;
} catch (error) {
console.error('Failed to get reminder items:', error);
return [];
}
}
// Get all pending reminder items
static getAllPendingReminders(): WKReminder[] {
// Here you need to iterate through all channels to get reminder items
// Actual implementation may require SDK to provide corresponding API
const allReminders: WKReminder[] = [];
// Example: Get reminder items for all conversations
const conversations = WKIM.shared.conversationManager().all();
for (const conv of conversations) {
const reminders = this.getChannelReminders(conv.channelId, conv.channelType, 0);
allReminders.push(...reminders);
}
return allReminders;
}
// Get completed reminder items
static getCompletedReminders(channelId: string, channelType: number): WKReminder[] {
return this.getChannelReminders(channelId, channelType, 1);
}
// Get reminder items by type
static getRemindersByType(channelId: string, channelType: number, type: number): WKReminder[] {
const allReminders = this.getChannelReminders(channelId, channelType, 0);
return allReminders.filter(reminder => reminder.type === type);
}
// Get @mention reminders
static getMentionReminders(channelId: string, channelType: number): WKReminder[] {
return this.getRemindersByType(channelId, channelType, ReminderType.mention);
}
// Get join request reminders
static getJoinRequestReminders(channelId: string, channelType: number): WKReminder[] {
return this.getRemindersByType(channelId, channelType, ReminderType.joinRequest);
}
// Get system notice reminders
static getSystemNoticeReminders(channelId: string, channelType: number): WKReminder[] {
return this.getRemindersByType(channelId, channelType, ReminderType.systemNotice);
}
// Count total reminders
static getTotalReminderCount(): number {
const allReminders = this.getAllPendingReminders();
return allReminders.length;
}
// Count reminders by type
static getReminderCountByType(): Map<number, number> {
const allReminders = this.getAllPendingReminders();
const countMap = new Map<number, number>();
for (const reminder of allReminders) {
const count = countMap.get(reminder.type) || 0;
countMap.set(reminder.type, count + 1);
}
return countMap;
}
// Check if there are unread reminders
static hasUnreadReminders(channelId: string, channelType: number): boolean {
const reminders = this.getChannelReminders(channelId, channelType, 0);
return reminders.length > 0;
}
// Get reminder display text
static getReminderDisplayText(reminder: WKReminder): string {
if (reminder.text) {
return reminder.text;
}
// Return default text based on type
switch (reminder.type) {
case ReminderType.mention:
return 'Someone mentioned me';
case ReminderType.joinRequest:
return 'Join request';
case ReminderType.systemNotice:
return 'System notice';
case ReminderType.unreadVoice:
return 'Unread voice';
default:
return 'New reminder';
}
}
}
// Reminder type constants
class ReminderType {
static readonly mention = 1; // @mention
static readonly joinRequest = 2; // Join request
static readonly systemNotice = 3; // System notice
static readonly unreadVoice = 4; // Unread voice
static readonly custom = 99; // Custom reminder
}
Save Reminder Items
Save or update reminder items
Copy
// Save reminder items
WKIM.shared.reminderManager().save(list: WKReminder[]);
Complete reminder item saving example
Copy
class ReminderOperations {
// Save single reminder item
static saveReminder(reminder: WKReminder): void {
try {
WKIM.shared.reminderManager().save([reminder]);
console.log('Reminder item saved successfully:', reminder.reminderId);
} catch (error) {
console.error('Failed to save reminder item:', error);
}
}
// Batch save reminder items
static batchSaveReminders(reminders: WKReminder[]): void {
try {
WKIM.shared.reminderManager().save(reminders);
console.log(`Batch saved ${reminders.length} reminder items successfully`);
} catch (error) {
console.error('Failed to batch save reminder items:', error);
}
}
// Mark reminder as done
static markReminderAsDone(reminder: WKReminder): void {
reminder.done = 1;
reminder.needUpload = 1; // Mark as needing upload to business server
this.saveReminder(reminder);
}
// Batch mark reminders as done
static batchMarkRemindersAsDone(reminders: WKReminder[]): void {
for (const reminder of reminders) {
reminder.done = 1;
reminder.needUpload = 1;
}
this.batchSaveReminders(reminders);
}
// Create @mention reminder
static createMentionReminder(options: {
messageId: string;
channelId: string;
channelType: number;
messageSeq: number;
mentionText: string;
publisher?: string;
}): WKReminder {
const reminder = new WKReminder();
reminder.messageId = options.messageId;
reminder.channelId = options.channelId;
reminder.channelType = options.channelType;
reminder.messageSeq = options.messageSeq;
reminder.type = ReminderType.mention;
reminder.text = options.mentionText;
reminder.publisher = options.publisher || '';
reminder.done = 0;
reminder.needUpload = 0;
reminder.version = Date.now();
return reminder;
}
// Create join request reminder
static createJoinRequestReminder(options: {
channelId: string;
channelType: number;
applicantName: string;
requestData: Record<string, Object>;
}): WKReminder {
const reminder = new WKReminder();
reminder.channelId = options.channelId;
reminder.channelType = options.channelType;
reminder.type = ReminderType.joinRequest;
reminder.text = `${options.applicantName} requests to join the group`;
reminder.data = options.requestData;
reminder.done = 0;
reminder.needUpload = 0;
reminder.version = Date.now();
return reminder;
}
// Create system notice reminder
static createSystemNoticeReminder(options: {
channelId: string;
channelType: number;
noticeText: string;
noticeData?: Record<string, Object>;
}): WKReminder {
const reminder = new WKReminder();
reminder.channelId = options.channelId;
reminder.channelType = options.channelType;
reminder.type = ReminderType.systemNotice;
reminder.text = options.noticeText;
reminder.data = options.noticeData;
reminder.done = 0;
reminder.needUpload = 0;
reminder.version = Date.now();
return reminder;
}
// Create unread voice reminder
static createUnreadVoiceReminder(options: {
messageId: string;
channelId: string;
channelType: number;
messageSeq: number;
voiceDuration: number;
}): WKReminder {
const reminder = new WKReminder();
reminder.messageId = options.messageId;
reminder.channelId = options.channelId;
reminder.channelType = options.channelType;
reminder.messageSeq = options.messageSeq;
reminder.type = ReminderType.unreadVoice;
reminder.text = 'Voice message unread';
reminder.data = { duration: options.voiceDuration };
reminder.done = 0;
reminder.needUpload = 0;
reminder.version = Date.now();
return reminder;
}
}
Event Listening
Add/Update Events
Copy
refreshReminders = (reminders: WKReminder[]): void => {
// Add reminder items or update reminder items
};
// Listen for reminder items
WKIM.shared.reminderManager().addRefreshListener(this.refreshReminders);
// Remove listener
WKIM.shared.reminderManager().removeRefreshListener(this.refreshReminders);
Complete event listening management
Copy
interface ReminderEvent {
type: ReminderEventType;
reminders: WKReminder[];
timestamp: number;
}
enum ReminderEventType {
refresh = 'refresh', // Refresh reminder
update = 'update', // Update reminder
delete = 'delete', // Delete reminder
}
class ReminderListener {
private static refreshListeners: Set<(reminders: WKReminder[]) => void> = new Set();
private static reminderEventCallbacks: Array<(event: ReminderEvent) => void> = [];
// Add reminder refresh listener
static addRefreshReminderListener(callback: (reminders: WKReminder[]) => void): void {
this.refreshListeners.add(callback);
WKIM.shared.reminderManager().addRefreshListener((reminders: WKReminder[]) => {
// Call callback
callback(reminders);
// Send to event callbacks
const event: ReminderEvent = {
type: ReminderEventType.refresh,
reminders,
timestamp: Date.now()
};
this.reminderEventCallbacks.forEach(cb => cb(event));
// Handle specific types of reminders
this.handleSpecificReminders(reminders);
console.log('Received reminder update:', reminders.length);
});
}
// Remove reminder refresh listener
static removeRefreshReminderListener(callback: (reminders: WKReminder[]) => void): void {
this.refreshListeners.delete(callback);
WKIM.shared.reminderManager().removeRefreshListener(callback);
}
// Add reminder event callback
static addReminderEventCallback(callback: (event: ReminderEvent) => void): void {
this.reminderEventCallbacks.push(callback);
}
// Remove reminder event callback
static removeReminderEventCallback(callback: (event: ReminderEvent) => void): void {
const index = this.reminderEventCallbacks.indexOf(callback);
if (index > -1) {
this.reminderEventCallbacks.splice(index, 1);
}
}
// Remove all listeners
static removeAllListeners(): void {
this.refreshListeners.forEach(callback => {
WKIM.shared.reminderManager().removeRefreshListener(callback);
});
this.refreshListeners.clear();
this.reminderEventCallbacks = [];
}
// Handle specific types of reminders
private static handleSpecificReminders(reminders: WKReminder[]): void {
for (const reminder of reminders) {
switch (reminder.type) {
case ReminderType.mention:
this.handleMentionReminder(reminder);
break;
case ReminderType.joinRequest:
this.handleJoinRequestReminder(reminder);
break;
case ReminderType.systemNotice:
this.handleSystemNoticeReminder(reminder);
break;
case ReminderType.unreadVoice:
this.handleUnreadVoiceReminder(reminder);
break;
default:
this.handleCustomReminder(reminder);
break;
}
}
}
// Handle @mention reminder
private static handleMentionReminder(reminder: WKReminder): void {
console.log('Handle @mention reminder:', reminder.text);
// Can trigger notifications, sounds, etc. here
this.showNotification('Someone mentioned me', reminder.text);
}
// Handle join request reminder
private static handleJoinRequestReminder(reminder: WKReminder): void {
console.log('Handle join request reminder:', reminder.text);
this.showNotification('Join request', reminder.text);
}
// Handle system notice reminder
private static handleSystemNoticeReminder(reminder: WKReminder): void {
console.log('Handle system notice reminder:', reminder.text);
this.showNotification('System notice', reminder.text);
}
// Handle unread voice reminder
private static handleUnreadVoiceReminder(reminder: WKReminder): void {
console.log('Handle unread voice reminder:', reminder.text);
this.showNotification('Voice message', reminder.text);
}
// Handle custom reminder
private static handleCustomReminder(reminder: WKReminder): void {
console.log('Handle custom reminder:', reminder.text);
this.showNotification('Reminder', reminder.text);
}
// Show notification
private static showNotification(title: string, content: string): void {
// Implement notification display logic
// Can use HarmonyOS notification API
}
// Add listener for specific channel
static addChannelReminderListener(channelId: string, channelType: number, callback: (reminders: WKReminder[]) => void): void {
const wrappedCallback = (reminders: WKReminder[]) => {
// Filter reminders for current channel
const channelReminders = reminders.filter(reminder =>
reminder.channelId === channelId && reminder.channelType === channelType
);
if (channelReminders.length > 0) {
callback(channelReminders);
}
};
this.addRefreshReminderListener(wrappedCallback);
}
// Dispose
static dispose(): void {
this.removeAllListeners();
}
}
Data Structure Description
WKReminder Reminder Object
Copy
export class WKReminder {
// Reminder item ID
reminderId = 0;
// Message ID
messageId = '';
// Channel ID
channelId: string = '';
// Channel type
channelType: number = WKChannelType.personal;
// Message sequence number
messageSeq = 0;
// Reminder item type 1.[@someone] 2.[join request] ...
type = 0;
// Display content
text = '';
// Reminder item content
data?: Record<string, Object>;
// Version number for incremental sync
version = 0;
// Whether completed 1.yes
done = 0;
// Whether needs upload to server
needUpload = 0;
// Publisher
publisher = '';
}
Field Description
| Field | Type | Description |
|---|---|---|
reminderId | number | Reminder item unique identifier |
messageId | string | Associated message ID |
channelId | string | Channel ID |
channelType | number | Channel type |
messageSeq | number | Message sequence number |
type | number | Reminder type (1=@mention, 2=join request, 3=system notice, 4=unread voice) |
text | string | Reminder display text |
data | Record | Additional data, can be any type |
version | number | Version number for synchronization |
done | number | Completion status (0=incomplete, 1=completed) |
needUpload | number | Whether needs upload to business server (0=no, 1=yes) |
publisher | string | Publisher ID |
Reminder Type Description
| Type Value | Description |
|---|---|
1 | @mention |
2 | Join request |
3 | System notice |
4 | Unread voice |
99 | Custom reminder |
HarmonyOS Component Integration Example
Reminder List Component
Copy
@Component
export struct ReminderListComponent {
@State private reminders: WKReminder[] = [];
@State private loading: boolean = true;
private channelId?: string;
private channelType?: number;
private refreshListener?: (reminders: WKReminder[]) => void;
constructor(channelId?: string, channelType?: number) {
this.channelId = channelId;
this.channelType = channelType;
}
aboutToAppear(): void {
this.loadReminders();
this.setupListener();
}
aboutToDisappear(): void {
if (this.refreshListener) {
ReminderListener.removeRefreshReminderListener(this.refreshListener);
}
}
private loadReminders(): void {
this.loading = true;
let reminders: WKReminder[];
if (this.channelId && this.channelType !== undefined) {
// Get reminders for specific channel
reminders = ReminderManager.getChannelReminders(this.channelId, this.channelType, 0);
} else {
// Get all reminders
reminders = ReminderManager.getAllPendingReminders();
}
this.reminders = reminders;
this.loading = false;
}
private setupListener(): void {
this.refreshListener = (reminders: WKReminder[]) => {
if (this.channelId && this.channelType !== undefined) {
// Filter reminders for specific channel
const channelReminders = reminders.filter(reminder =>
reminder.channelId === this.channelId && reminder.channelType === this.channelType
);
if (channelReminders.length > 0) {
this.loadReminders();
}
} else {
// Refresh all reminders
this.loadReminders();
}
};
ReminderListener.addRefreshReminderListener(this.refreshListener);
}
build() {
Column() {
// Title bar
Row() {
Text('Reminder Messages')
.fontSize(18)
.fontWeight(FontWeight.Bold)
Blank()
if (this.reminders.length > 0) {
Button('Mark All Read')
.fontSize(14)
.onClick(() => {
this.markAllAsDone();
})
}
}
.width('100%')
.padding(16)
// Reminder list
if (this.loading) {
Column() {
LoadingProgress()
.width(40)
.height(40)
Text('Loading...')
.margin({ top: 8 })
}
.justifyContent(FlexAlign.Center)
.layoutWeight(1)
} else if (this.reminders.length === 0) {
Column() {
Image($r('app.media.empty_reminder'))
.width(64)
.height(64)
.margin({ bottom: 16 })
Text('No reminders')
.fontSize(16)
.fontColor(Color.Grey)
}
.justifyContent(FlexAlign.Center)
.layoutWeight(1)
} else {
List() {
ForEach(this.reminders, (reminder: WKReminder) => {
ListItem() {
this.buildReminderItem(reminder)
}
})
}
.layoutWeight(1)
}
}
.width('100%')
.height('100%')
}
@Builder
private buildReminderItem(reminder: WKReminder) {
Row() {
// Reminder icon
Circle({ width: 40, height: 40 })
.fill(this.getReminderColor(reminder.type))
.margin({ right: 12 })
.overlay(
Image(this.getReminderIcon(reminder.type))
.width(20)
.height(20)
.fillColor(Color.White)
)
Column() {
// Reminder title
Text(ReminderManager.getReminderDisplayText(reminder))
.fontSize(16)
.fontWeight(FontWeight.Medium)
.maxLines(1)
.textOverflow({ overflow: TextOverflow.Ellipsis })
// Reminder content
if (reminder.text && reminder.text !== ReminderManager.getReminderDisplayText(reminder)) {
Text(reminder.text)
.fontSize(14)
.fontColor(Color.Grey)
.maxLines(2)
.textOverflow({ overflow: TextOverflow.Ellipsis })
.margin({ top: 2 })
}
// Channel info
Text(`Channel: ${reminder.channelId}`)
.fontSize(12)
.fontColor(Color.Grey)
.margin({ top: 4 })
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
// Reminder type tag
Text(this.getReminderTypeText(reminder.type))
.fontSize(10)
.fontColor(Color.White)
.backgroundColor(this.getReminderColor(reminder.type))
.padding({ left: 6, right: 6, top: 2, bottom: 2 })
.borderRadius(8)
}
.width('100%')
.padding(12)
.alignItems(VerticalAlign.Top)
.onClick(() => {
this.handleReminderTap(reminder);
})
}
private getReminderColor(type: number): Color {
switch (type) {
case ReminderType.mention:
return Color.Orange;
case ReminderType.joinRequest:
return Color.Blue;
case ReminderType.systemNotice:
return Color.Green;
case ReminderType.unreadVoice:
return Color.Purple;
default:
return Color.Grey;
}
}
private getReminderIcon(type: number): Resource {
switch (type) {
case ReminderType.mention:
return $r('app.media.ic_mention');
case ReminderType.joinRequest:
return $r('app.media.ic_person_add');
case ReminderType.systemNotice:
return $r('app.media.ic_info');
case ReminderType.unreadVoice:
return $r('app.media.ic_mic');
default:
return $r('app.media.ic_notifications');
}
}
private getReminderTypeText(type: number): string {
switch (type) {
case ReminderType.mention:
return '@Mention';
case ReminderType.joinRequest:
return 'Join Request';
case ReminderType.systemNotice:
return 'System Notice';
case ReminderType.unreadVoice:
return 'Unread Voice';
default:
return 'Reminder';
}
}
private handleReminderTap(reminder: WKReminder): void {
// Handle reminder tap event
if (reminder.messageId) {
// Navigate to corresponding message
this.navigateToMessage(reminder);
} else {
// Handle other types of reminders
this.handleSpecialReminder(reminder);
}
// Mark as read
this.markReminderAsDone(reminder);
}
private navigateToMessage(reminder: WKReminder): void {
// Navigate to message page
console.log('Navigate to message:', reminder.messageId);
}
private handleSpecialReminder(reminder: WKReminder): void {
// Handle special reminders
console.log('Handle special reminder:', reminder.type);
}
private markReminderAsDone(reminder: WKReminder): void {
ReminderOperations.markReminderAsDone(reminder);
// Remove from list
const index = this.reminders.indexOf(reminder);
if (index > -1) {
this.reminders.splice(index, 1);
}
}
private markAllAsDone(): void {
ReminderOperations.batchMarkRemindersAsDone(this.reminders);
this.reminders = [];
}
}

