Skip to content

Commit 9e3b269

Browse files
committed
feat: Generate local notification for outgoing messages
Outgoing messages will trigger a local-notification event. The API will now allow outgoing notification identification by using the new `IsFromMe` bool
1 parent 4550312 commit 9e3b269

File tree

3 files changed

+93
-34
lines changed

3 files changed

+93
-34
lines changed

protocol/local_notifications.go

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ const (
2626

2727
// MessagePreview values (must match Constants.settingsSection.notificationsBubble)
2828
const (
29-
messagePreviewAnonymous = 0
30-
messagePreviewNameOnly = 1
29+
messagePreviewAnonymous = 0
30+
messagePreviewNameOnly = 1
3131
messagePreviewNameAndMessage = 2
3232
)
3333

@@ -281,6 +281,43 @@ func NewCommunityRequestToJoinNotification(id string, community *communities.Com
281281
return body.toCommunityRequestToJoinNotification(id, profilePicturesVisibility, messagePreview)
282282
}
283283

284+
// NewOutgoingMessageNotification creates a local notification for a message sent by the current user.
285+
func NewOutgoingMessageNotification(id string, message *common.Message, chat *Chat, community *communities.Community, authorName string, authorIcon string, authorID string) *localnotifications.Notification {
286+
title := chat.Name
287+
simplifiedText, err := message.GetSimplifiedText("", nil)
288+
if err != nil {
289+
simplifiedText = message.Text
290+
}
291+
notif := &localnotifications.Notification{
292+
ID: gethcommon.HexToHash(id),
293+
BodyType: localnotifications.TypeMessage,
294+
Category: localnotifications.CategoryMessage,
295+
Deeplink: chat.DeepLink(),
296+
Title: title,
297+
Message: simplifiedText,
298+
DisplayTitle: title,
299+
DisplayMessage: simplifiedText,
300+
IsConversation: true,
301+
IsGroupConversation: chat.PrivateGroupChat() || chat.Public() || chat.CommunityChat(),
302+
Author: localnotifications.NotificationAuthor{
303+
Name: authorName,
304+
Icon: authorIcon,
305+
ID: authorID,
306+
},
307+
Timestamp: message.WhisperTimestamp,
308+
ConversationID: chat.ID,
309+
Image: "",
310+
IsFromMe: true,
311+
}
312+
if chat.CommunityChat() && community != nil {
313+
notif.CommunityIcon = communityIconDataURI(community)
314+
}
315+
if chat.PrivateGroupChat() {
316+
notif.ChatIcon = chatIconDataURI(chat)
317+
}
318+
return notif
319+
}
320+
284321
func NewPrivateGroupInviteNotification(id string, chat *Chat, contact *contacts.Contact, profilePicturesVisibility int, messagePreview int) *localnotifications.Notification {
285322
body := &NotificationBody{
286323
Chat: chat,
@@ -326,8 +363,8 @@ func (n NotificationBody) toMessageNotification(id string, resolvePrimaryName fu
326363
Title: title,
327364
Message: simplifiedText,
328365
DisplayTitle: displayTitle,
329-
DisplayMessage: displayMessage,
330-
IsConversation: true,
366+
DisplayMessage: displayMessage,
367+
IsConversation: true,
331368
IsGroupConversation: true,
332369
Author: localnotifications.NotificationAuthor{
333370
Name: n.Contact.PrimaryName(),

protocol/messenger.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,6 +2115,24 @@ func (m *Messenger) sendChatMessage(ctx context.Context, message *common.Message
21152115
return nil, err
21162116
}
21172117

2118+
// Push outgoing message to local-notifications so clients (e.g. Android) receive it
2119+
// via the same signal path as incoming messages and can refresh the notification.
2120+
var community *communities.Community
2121+
if chat.CommunityChat() && chat.CommunityID != "" {
2122+
community, _ = m.communitiesManager.GetByIDString(chat.CommunityID)
2123+
}
2124+
authorID := crypto.PubkeyToHex(&m.identity.PublicKey)
2125+
authorName, _ := m.settings.DisplayName()
2126+
var authorIcon string
2127+
if img, err := m.multiAccounts.GetIdentityImage(m.account.KeyUID, images.SmallDimName); err == nil && img != nil && len(img.Payload) > 0 {
2128+
authorIcon, _ = images.GetPayloadDataURI(img.Payload)
2129+
}
2130+
if authorIcon == "" {
2131+
authorIcon, _ = identicon.GenerateBase64(authorID)
2132+
}
2133+
outgoingNotif := NewOutgoingMessageNotification(message.ID, message, chat, community, authorName, authorIcon, authorID)
2134+
localnotifications.PushMessages([]*localnotifications.Notification{outgoingNotif})
2135+
21182136
return &response, m.saveChat(chat)
21192137
}
21202138

services/local-notifications/core.go

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@ type NotificationBody interface {
2121
}
2222

2323
type Notification struct {
24-
ID common.Hash
25-
Platform float32
26-
Body NotificationBody
27-
BodyType NotificationType
28-
Title string
29-
Message string
24+
ID common.Hash
25+
Platform float32
26+
Body NotificationBody
27+
BodyType NotificationType
28+
Title string
29+
Message string
3030
// DisplayTitle and DisplayMessage are privacy-filtered for lock screen/OS display.
3131
// When set, clients should use these for OS notifications; Title/Message remain full for in-app.
32-
DisplayTitle string
33-
DisplayMessage string
32+
DisplayTitle string
33+
DisplayMessage string
3434
Category PushCategory
3535
Deeplink string
3636
Image string
@@ -45,7 +45,9 @@ type Notification struct {
4545
CommunityIcon string
4646
// ChatIcon is the chat/group avatar (data URI) for group chat notifications.
4747
ChatIcon string
48-
Deleted bool
48+
Deleted bool
49+
// IsFromMe indicates the message was sent by the current user (outgoing).
50+
IsFromMe bool
4951
}
5052

5153
type NotificationAuthor struct {
@@ -56,27 +58,28 @@ type NotificationAuthor struct {
5658

5759
// notificationAlias is an interim struct used for json un/marshalling
5860
type notificationAlias struct {
59-
ID common.Hash `json:"id"`
60-
Platform float32 `json:"platform,omitempty"`
61-
Body json.RawMessage `json:"body"`
62-
BodyType NotificationType `json:"bodyType"`
63-
Title string `json:"title,omitempty"`
64-
Message string `json:"message,omitempty"`
65-
DisplayTitle string `json:"displayTitle,omitempty"`
66-
DisplayMessage string `json:"displayMessage,omitempty"`
67-
Category PushCategory `json:"category,omitempty"`
68-
Deeplink string `json:"deepLink,omitempty"`
69-
Image string `json:"imageUrl,omitempty"`
70-
IsScheduled bool `json:"isScheduled,omitempty"`
71-
ScheduledTime string `json:"scheduleTime,omitempty"`
72-
IsConversation bool `json:"isConversation,omitempty"`
73-
IsGroupConversation bool `json:"isGroupConversation,omitempty"`
74-
ConversationID string `json:"conversationId,omitempty"`
75-
Timestamp uint64 `json:"timestamp,omitempty"`
76-
Author NotificationAuthor `json:"notificationAuthor,omitempty"`
77-
CommunityIcon string `json:"communityIcon,omitempty"`
78-
ChatIcon string `json:"chatIcon,omitempty"`
79-
Deleted bool `json:"deleted,omitempty"`
61+
ID common.Hash `json:"id"`
62+
Platform float32 `json:"platform,omitempty"`
63+
Body json.RawMessage `json:"body"`
64+
BodyType NotificationType `json:"bodyType"`
65+
Title string `json:"title,omitempty"`
66+
Message string `json:"message,omitempty"`
67+
DisplayTitle string `json:"displayTitle,omitempty"`
68+
DisplayMessage string `json:"displayMessage,omitempty"`
69+
Category PushCategory `json:"category,omitempty"`
70+
Deeplink string `json:"deepLink,omitempty"`
71+
Image string `json:"imageUrl,omitempty"`
72+
IsScheduled bool `json:"isScheduled,omitempty"`
73+
ScheduledTime string `json:"scheduleTime,omitempty"`
74+
IsConversation bool `json:"isConversation,omitempty"`
75+
IsGroupConversation bool `json:"isGroupConversation,omitempty"`
76+
ConversationID string `json:"conversationId,omitempty"`
77+
Timestamp uint64 `json:"timestamp,omitempty"`
78+
Author NotificationAuthor `json:"notificationAuthor,omitempty"`
79+
CommunityIcon string `json:"communityIcon,omitempty"`
80+
ChatIcon string `json:"chatIcon,omitempty"`
81+
Deleted bool `json:"deleted,omitempty"`
82+
IsFromMe bool `json:"isFromMe,omitempty"`
8083
}
8184

8285
// MessageEvent - structure used to pass messages from chat to bus
@@ -132,6 +135,7 @@ func (n *Notification) MarshalJSON() ([]byte, error) {
132135
CommunityIcon: n.CommunityIcon,
133136
ChatIcon: n.ChatIcon,
134137
Deleted: n.Deleted,
138+
IsFromMe: n.IsFromMe,
135139
}
136140

137141
return json.Marshal(alias)

0 commit comments

Comments
 (0)