2022-04-25 21:03:24 +00:00
|
|
|
// Copyright 2018-2022 Signal Messenger, LLC
|
2020-10-30 20:34:04 +00:00
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
2018-04-10 00:05:36 +00:00
|
|
|
import * as Attachment from '../Attachment';
|
Index messages with attachments using a boolean
When indexing message attachment metadata using numeric indexes such as:
```javascript
{
conversationId: '+12223334455',
received_at: 123,
attachments: […],
numAttachments: 2,
},
{
conversationId: '+12223334455',
received_at: 456,
attachments: [],
numAttachments: 0,
}
{
conversationId: '+12223334455',
received_at: 789,
attachments: [],
numAttachments: 1,
}
```
It creates an index as follows:
```
[conversationId, received_at, numAttachments]
['+12223334455', 123, 2]
['+12223334455', 456, 0]
['+12223334455', 789, 1]
```
This means a query such as…
```
lowerBound: ['+12223334455', 0, 1 ]
upperBound: ['+12223334455', Number.MAX_VALUE, Number.MAX_VALUE]
```
…will return all three original entries because they span the `received_at`
from `0` through `Number.MAX_VALUE`. One workaround is to index booleans using
`1 | undefined` where `1` is included in the index and `undefined` is not, but
that way we lose the ability to query for the `false` value. Instead, we flip
adjust the index to `[conversationId, hasAttachments, received_at]` and can
then query messages with attachments using
```
[conversationId, 1 /* hasAttachments */, 0 /* received_at */]
[conversationId, 1 /* hasAttachments */, Number.MAX_VALUE /* received_at */]
```
2018-04-14 01:47:06 +00:00
|
|
|
import * as IndexedDB from '../IndexedDB';
|
2022-06-10 01:10:20 +00:00
|
|
|
|
|
|
|
import type { MessageAttributesType } from '../../model-types.d';
|
2018-05-07 19:50:39 +00:00
|
|
|
|
2021-11-11 22:43:05 +00:00
|
|
|
const hasAttachment =
|
|
|
|
(predicate: (value: Attachment.AttachmentType) => boolean) =>
|
2022-06-10 01:10:20 +00:00
|
|
|
(message: MessageAttributesType): IndexedDB.IndexablePresence =>
|
|
|
|
IndexedDB.toIndexablePresence((message.attachments || []).some(predicate));
|
2018-05-07 19:50:39 +00:00
|
|
|
|
|
|
|
const hasFileAttachment = hasAttachment(Attachment.isFile);
|
|
|
|
const hasVisualMediaAttachment = hasAttachment(Attachment.isVisualMedia);
|
2018-04-10 00:05:36 +00:00
|
|
|
|
2018-04-13 20:25:52 +00:00
|
|
|
export const initializeAttachmentMetadata = async (
|
2022-06-10 01:10:20 +00:00
|
|
|
message: MessageAttributesType
|
|
|
|
): Promise<MessageAttributesType> => {
|
2018-04-13 20:27:38 +00:00
|
|
|
if (message.type === 'verified-change') {
|
|
|
|
return message;
|
|
|
|
}
|
2020-07-29 23:20:05 +00:00
|
|
|
if (message.type === 'profile-change') {
|
|
|
|
return message;
|
|
|
|
}
|
2019-08-05 20:53:15 +00:00
|
|
|
if (message.messageTimer || message.isViewOnce) {
|
2019-06-26 19:33:13 +00:00
|
|
|
return message;
|
|
|
|
}
|
2018-04-13 20:27:38 +00:00
|
|
|
|
2022-06-10 01:10:20 +00:00
|
|
|
const attachments = (message.attachments || []).filter(
|
2021-07-14 23:39:52 +00:00
|
|
|
(attachment: Attachment.AttachmentType) =>
|
2019-06-21 21:06:37 +00:00
|
|
|
attachment.contentType !== 'text/x-signal-plain'
|
2018-04-14 02:09:56 +00:00
|
|
|
);
|
2019-06-21 21:06:37 +00:00
|
|
|
const hasAttachments = IndexedDB.toIndexableBoolean(attachments.length > 0);
|
2018-05-07 19:50:39 +00:00
|
|
|
|
2019-06-21 21:06:37 +00:00
|
|
|
const hasFileAttachments = hasFileAttachment({ ...message, attachments });
|
|
|
|
const hasVisualMediaAttachments = hasVisualMediaAttachment({
|
|
|
|
...message,
|
|
|
|
attachments,
|
|
|
|
});
|
2018-04-10 00:05:36 +00:00
|
|
|
|
2018-04-13 20:25:52 +00:00
|
|
|
return {
|
|
|
|
...message,
|
Index messages with attachments using a boolean
When indexing message attachment metadata using numeric indexes such as:
```javascript
{
conversationId: '+12223334455',
received_at: 123,
attachments: […],
numAttachments: 2,
},
{
conversationId: '+12223334455',
received_at: 456,
attachments: [],
numAttachments: 0,
}
{
conversationId: '+12223334455',
received_at: 789,
attachments: [],
numAttachments: 1,
}
```
It creates an index as follows:
```
[conversationId, received_at, numAttachments]
['+12223334455', 123, 2]
['+12223334455', 456, 0]
['+12223334455', 789, 1]
```
This means a query such as…
```
lowerBound: ['+12223334455', 0, 1 ]
upperBound: ['+12223334455', Number.MAX_VALUE, Number.MAX_VALUE]
```
…will return all three original entries because they span the `received_at`
from `0` through `Number.MAX_VALUE`. One workaround is to index booleans using
`1 | undefined` where `1` is included in the index and `undefined` is not, but
that way we lose the ability to query for the `false` value. Instead, we flip
adjust the index to `[conversationId, hasAttachments, received_at]` and can
then query messages with attachments using
```
[conversationId, 1 /* hasAttachments */, 0 /* received_at */]
[conversationId, 1 /* hasAttachments */, Number.MAX_VALUE /* received_at */]
```
2018-04-14 01:47:06 +00:00
|
|
|
hasAttachments,
|
|
|
|
hasFileAttachments,
|
2018-05-07 19:50:39 +00:00
|
|
|
hasVisualMediaAttachments,
|
2018-04-10 00:05:36 +00:00
|
|
|
};
|
2018-04-13 20:25:52 +00:00
|
|
|
};
|