Friend request message indicator.

pull/28/head
Mikunj 7 years ago
parent b9e85bb141
commit c150cbe34f

@ -92,6 +92,8 @@
conversation: this, conversation: this,
}); });
this.pendingFriendRequest = false;
this.messageCollection.on('change:errors', this.handleMessageError, this); this.messageCollection.on('change:errors', this.handleMessageError, this);
this.messageCollection.on('send-error', this.onMessageError, this); this.messageCollection.on('send-error', this.onMessageError, this);
@ -202,6 +204,32 @@
title: this.getTitle(), title: this.getTitle(),
}; };
}, },
// This function sets `pendingFriendRequest` variable in memory
async updatePendingFriendRequests() {
const pendingFriendRequest = await this.hasPendingFriendRequests();
// Only update if we have different values
if (this.pendingFriendRequest !== pendingFriendRequest) {
this.pendingFriendRequest = pendingFriendRequest;
// trigger an update
this.trigger('change');
}
},
// This goes through all our message history and finds a friend request
// But this is not a concurrent operation and thus `updatePendingFriendRequests` is used
async hasPendingFriendRequests() {
// Go through the messages and check for any pending friend requests
const messages = await window.Signal.Data.getMessagesByConversation(
this.id,
{ MessageCollection: Whisper.MessageCollection }
);
for (let i = 0; i < messages.models.length; ++i) {
const message = messages.models[i];
if (message.isFriendRequest() && message.attributes.status === 'pending') return true;
}
return false;
},
getPropsForListItem() { getPropsForListItem() {
const result = { const result = {
...this.format(), ...this.format(),
@ -210,7 +238,7 @@
lastUpdated: this.get('timestamp'), lastUpdated: this.get('timestamp'),
unreadCount: this.get('unreadCount') || 0, unreadCount: this.get('unreadCount') || 0,
isSelected: this.isSelected, isSelected: this.isSelected,
showFriendRequestIndicator: this.pendingFriendRequest,
lastMessage: { lastMessage: {
status: this.lastMessageStatus, status: this.lastMessageStatus,
text: this.lastMessage, text: this.lastMessage,
@ -566,8 +594,7 @@
); );
}, },
// This will add a message which will allow the user to reply to a friend request // This will add a message which will allow the user to reply to a friend request
// TODO: Maybe add callbacks for accept and decline? async addFriendRequest(body, status = 'pending', type = 'incoming') {
async addFriendRequest(body, type = 'incoming') {
if (this.isMe()) { if (this.isMe()) {
window.log.info( window.log.info(
'refusing to send friend request to ourselves' 'refusing to send friend request to ourselves'
@ -584,6 +611,17 @@
lastMessage lastMessage
); );
this.lastMessageStatus = 'sending';
this.set({
active_at: Date.now(),
timestamp: Date.now(),
});
await window.Signal.Data.updateConversation(this.id, this.attributes, {
Conversation: Whisper.Conversation,
});
const timestamp = Date.now(); const timestamp = Date.now();
const message = { const message = {
conversationId: this.id, conversationId: this.id,
@ -593,7 +631,7 @@
unread: 1, unread: 1,
from: this.id, from: this.id,
to: this.ourNumber, to: this.ourNumber,
status: 'pending', status,
requestType: type, requestType: type,
body, body,
}; };
@ -601,7 +639,7 @@
const id = await window.Signal.Data.saveMessage(message, { const id = await window.Signal.Data.saveMessage(message, {
Message: Whisper.Message, Message: Whisper.Message,
}); });
this.trigger( this.trigger(
'newmessage', 'newmessage',
new Whisper.Message({ new Whisper.Message({
@ -902,6 +940,9 @@
return; return;
} }
// Update our friend indicator
this.updatePendingFriendRequests();
const messages = await window.Signal.Data.getMessagesByConversation( const messages = await window.Signal.Data.getMessagesByConversation(
this.id, this.id,
{ limit: 1, MessageCollection: Whisper.MessageCollection } { limit: 1, MessageCollection: Whisper.MessageCollection }

@ -182,10 +182,8 @@
const controller = window.ConversationController; const controller = window.ConversationController;
const conversation = await controller.getOrCreateAndWait(pubKey, 'private'); const conversation = await controller.getOrCreateAndWait(pubKey, 'private');
if (conversation) { if (conversation) {
conversation.addFriendRequest(message, 'incoming'); conversation.addFriendRequest(message);
} }
this.openConversation(conversation);
}, },
}); });
})(); })();

@ -837,7 +837,6 @@ MessageReceiver.prototype.extend({
}); });
}, },
promptUserToAcceptFriendRequest(pubKey, message) { promptUserToAcceptFriendRequest(pubKey, message) {
// pubKey = pubKey.slice(0, 30) + '...';
window.Whisper.events.trigger('showFriendRequest', { window.Whisper.events.trigger('showFriendRequest', {
pubKey, pubKey,
message, message,
@ -846,6 +845,15 @@ MessageReceiver.prototype.extend({
// A handler function for when a friend request is accepted or declined // A handler function for when a friend request is accepted or declined
onFriendRequestUpdate(pubKey, message) { onFriendRequestUpdate(pubKey, message) {
if (!message || !message.requestType || !message.status) return; if (!message || !message.requestType || !message.status) return;
// Update the conversation
const conversation = ConversationController.get(pubKey);
if (conversation) {
// Update the conversation friend request indicator
conversation.updatePendingFriendRequests();
}
// Send our own prekeys as a response
if (message.requestType === 'incoming' && message.status === 'accepted') { if (message.requestType === 'incoming' && message.status === 'accepted') {
libloki.sendEmptyMessageWithPreKeys(pubKey); libloki.sendEmptyMessageWithPreKeys(pubKey);
} }

@ -1796,6 +1796,11 @@
border-left: 4px solid $color-signal-blue; border-left: 4px solid $color-signal-blue;
} }
.module-conversation-list-item--has-friend-request {
padding-left: 12px;
border-left: 4px solid $color-conversation-indigo;
}
.module-conversation-list-item--is-selected { .module-conversation-list-item--is-selected {
background-color: $color-gray-05; background-color: $color-gray-05;
} }

@ -1261,6 +1261,10 @@ body.dark-theme {
border-left: 4px solid $color-signal-blue; border-left: 4px solid $color-signal-blue;
} }
.module-conversation-list-item--has-friend-request {
border-left: 4px solid $color-conversation-indigo;
}
.module-conversation-list-item--is-selected { .module-conversation-list-item--is-selected {
background-color: $color-dark-70; background-color: $color-dark-70;
} }

@ -23,6 +23,7 @@ interface Props {
status: 'sending' | 'sent' | 'delivered' | 'read' | 'error'; status: 'sending' | 'sent' | 'delivered' | 'read' | 'error';
text: string; text: string;
}; };
showFriendRequestIndicator?: boolean;
i18n: Localizer; i18n: Localizer;
onClick?: () => void; onClick?: () => void;
@ -156,7 +157,7 @@ export class ConversationListItem extends React.Component<Props> {
} }
public render() { public render() {
const { unreadCount, onClick, isSelected } = this.props; const { unreadCount, onClick, isSelected, showFriendRequestIndicator } = this.props;
return ( return (
<div <div
@ -165,7 +166,8 @@ export class ConversationListItem extends React.Component<Props> {
className={classNames( className={classNames(
'module-conversation-list-item', 'module-conversation-list-item',
unreadCount > 0 ? 'module-conversation-list-item--has-unread' : null, unreadCount > 0 ? 'module-conversation-list-item--has-unread' : null,
isSelected ? 'module-conversation-list-item--is-selected' : null isSelected ? 'module-conversation-list-item--is-selected' : null,
showFriendRequestIndicator ? 'module-conversation-list-item--has-friend-request' : null
)} )}
> >
{this.renderAvatar()} {this.renderAvatar()}

Loading…
Cancel
Save