feat: added lastMessageId to convo model to uniquely identify a lastMessage

pull/2789/head
William Grant 2 years ago
parent 30b486c80e
commit de614109d0

@ -27,7 +27,8 @@ export const InteractionItem = (props: InteractionItemProps) => {
const isGroup = !useIsPrivate(conversationId);
const isCommunity = useIsPublic(conversationId);
const [storedLastMessage, setStoredLastMessage] = useState(lastMessage?.text);
const [storedLastMessageId, setStoredLastMessageId] = useState(lastMessage?.id);
const [storedLastMessageText, setStoredLastMessageText] = useState(lastMessage?.text);
// NOTE we want to reset the interaction state when the last message changes
useEffect(() => {
@ -35,23 +36,24 @@ export const InteractionItem = (props: InteractionItemProps) => {
const convo = getConversationController().get(conversationId);
window.log.debug(
`WIP: storedLastMessage "${storedLastMessage}" convo.get('lastMessage') "${convo.get(
'lastMessage'
)}'`
`WIP: storedLastMessageId "${storedLastMessageId}" convo.get('lastMessageId') "${convo.get(
'lastMessageId'
)}' lastMessageId ${JSON.stringify(lastMessage)}`
);
if (storedLastMessage !== convo.get('lastMessage')) {
setStoredLastMessage(convo.get('lastMessage'));
if (storedLastMessageId !== convo.get('lastMessageId')) {
setStoredLastMessageId(convo.get('lastMessageId'));
setStoredLastMessageText(convo.get('lastMessage'));
void clearConversationInteractionState({ conversationId });
}
}
}, [conversationId, interactionStatus, lastMessage?.text]);
}, [conversationId, interactionStatus, lastMessage?.id]);
if (isEmpty(conversationId) || isEmpty(interactionType) || isEmpty(interactionStatus)) {
return null;
}
let text = storedLastMessage || '';
let text = storedLastMessageText || '';
switch (interactionType) {
case ConversationInteractionType.Leave:
const failText = isCommunity

@ -426,6 +426,7 @@ export async function deleteAllMessagesByConvoIdNoConfirmation(conversationId: s
// conversation still appears on the conversation list but is empty
conversation.set({
lastMessage: null,
lastMessageId: null,
});
await conversation.commit();

@ -389,9 +389,11 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
// -- Handle the last message status, if present --
const lastMessageText = this.get('lastMessage');
if (lastMessageText && lastMessageText.length) {
const lastMessageId = this.get('lastMessageId');
const lastMessageStatus = this.get('lastMessageStatus');
toRet.lastMessage = {
id: lastMessageId,
status: lastMessageStatus,
text: lastMessageText,
};
@ -753,6 +755,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
this.set({
lastMessage: messageModel.getNotificationText(),
lastMessageId: messageModel.get('id'),
lastMessageStatus: 'sending',
active_at: networkTimestamp,
});
@ -1853,6 +1856,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
return;
}
const lastMessageModel = messages.at(0);
const lastMessageId = lastMessageModel.get('id');
const lastMessageStatus = lastMessageModel.getMessagePropStatus() || undefined;
const lastMessageNotificationText = lastMessageModel.getNotificationText() || undefined;
// we just want to set the `status` to `undefined` if there are no `lastMessageNotificationText`
@ -1860,17 +1864,21 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
!!lastMessageNotificationText && !isEmpty(lastMessageNotificationText)
? {
lastMessage: lastMessageNotificationText || '',
lastMessageId,
lastMessageStatus,
}
: { lastMessage: '', lastMessageStatus: undefined };
: { lastMessage: '', lastMessageId: '', lastMessageStatus: undefined };
const existingLastMessageAttribute = this.get('lastMessage');
const existingLastMessageId = this.get('lastMessageId');
const existingLastMessageStatus = this.get('lastMessageStatus');
if (
lastMessageUpdate.lastMessage !== existingLastMessageAttribute ||
lastMessageUpdate.lastMessageStatus !== existingLastMessageStatus
lastMessageUpdate.lastMessageStatus !== existingLastMessageStatus ||
lastMessageUpdate.lastMessageId !== existingLastMessageId
) {
if (
lastMessageUpdate.lastMessageId === existingLastMessageId &&
lastMessageUpdate.lastMessageStatus === existingLastMessageStatus &&
lastMessageUpdate.lastMessage &&
lastMessageUpdate.lastMessage.length > 40 &&

@ -59,7 +59,6 @@ export interface ConversationAttributes {
// 0 means inactive (undefined and null too but we try to get rid of them and only have 0 = inactive)
active_at: number; // this field is the one used to sort conversations in the left pane from most recent
lastMessageStatus: LastMessageStatusType;
/**
* lastMessage is actually just a preview of the last message text, shortened to 60 chars.
* This is to avoid filling the redux store with a huge last message when it's only used in the
@ -67,6 +66,8 @@ export interface ConversationAttributes {
* The shortening is made in sql.ts directly.
*/
lastMessage: string | null;
lastMessageId: string | null;
lastMessageStatus: LastMessageStatusType;
avatarImageId?: number; // avatar imageID is currently used only for sogs. It's the fileID of the image uploaded and set as the sogs avatar (not only sogs I think, but our profile too?)
@ -129,8 +130,9 @@ export const fillConvoAttributesWithDefaults = (
expireTimer: 0,
active_at: 0,
lastMessageStatus: undefined,
lastMessage: null,
lastMessageId: null,
lastMessageStatus: undefined,
triggerNotificationsFor: 'all', // if the settings is not set in the db, this is the default

@ -58,6 +58,7 @@ const allowedKeysFormatRowOfConversation = [
'isKickedFromGroup',
'left',
'lastMessage',
'lastMessageId',
'lastMessageStatus',
'triggerNotificationsFor',
'unreadCount',
@ -138,6 +139,10 @@ export function formatRowOfConversation(
convo.lastMessage = null;
}
if (!convo.lastMessageId) {
convo.lastMessageId = null;
}
if (!convo.lastMessageStatus) {
convo.lastMessageStatus = undefined;
}
@ -178,6 +183,7 @@ const allowedKeysOfConversationAttributes = [
'isKickedFromGroup',
'left',
'lastMessage',
'lastMessageId',
'lastMessageStatus',
'triggerNotificationsFor',
'lastJoinedTimestamp',

@ -1846,6 +1846,8 @@ function updateToSessionSchemaVersion32(currentVersion: number, db: BetterSqlite
db.prepare(`ALTER TABLE ${CONVERSATIONS_TABLE} ADD COLUMN interactionStatus TEXT;`).run();
db.prepare(`ALTER TABLE ${CONVERSATIONS_TABLE} ADD COLUMN lastMessageId TEXT;`).run();
writeSessionSchemaVersion(targetVersion, db);
})();

@ -427,8 +427,9 @@ function saveConversation(data: ConversationAttributes): SaveConversationReturn
zombies,
left,
expireTimer,
lastMessageStatus,
lastMessage,
lastMessageId,
lastMessageStatus,
lastJoinedTimestamp,
groupAdmins,
isKickedFromGroup,
@ -477,8 +478,9 @@ function saveConversation(data: ConversationAttributes): SaveConversationReturn
zombies: zombies && zombies.length ? arrayStrToJson(zombies) : '[]',
left: toSqliteBoolean(left),
expireTimer,
lastMessageStatus,
lastMessage: shortenedLastMessage,
lastMessageId,
lastMessageStatus,
lastJoinedTimestamp,
groupAdmins: groupAdmins && groupAdmins.length ? arrayStrToJson(groupAdmins) : '[]',

@ -276,6 +276,7 @@ async function handleRegularMessage(
conversation.set({
active_at: message.get('sent_at'),
lastMessage: message.getNotificationText(),
lastMessageId: message.get('id'),
});
// a new message was received for that conversation. If it was not it should not be hidden anymore
await conversation.unhideIfNeeded(false);

@ -217,6 +217,7 @@ export type PropsForMessageWithConvoProps = PropsForMessageWithoutConvoProps & {
};
export type LastMessageType = {
id: string | null;
status: LastMessageStatusType;
text: string | null;
};

Loading…
Cancel
Save