mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-04-23 09:58:12 +01:00
Add receive support for pin/unpin message
This commit is contained in:
@@ -15,14 +15,25 @@ export function getPinnedMessagesForConversation(
|
||||
conversationId: string
|
||||
): ReadonlyArray<PinnedMessage> {
|
||||
const [query, params] = sql`
|
||||
SELECT * FROM pins
|
||||
SELECT * FROM pinnedMessages
|
||||
WHERE conversationId = ${conversationId}
|
||||
ORDER BY pinnedAt DESC
|
||||
`;
|
||||
return db.prepare(query).all<PinnedMessage>(params);
|
||||
}
|
||||
|
||||
export function createPinnedMessage(
|
||||
function _getPinnedMessageByMessageId(
|
||||
db: ReadableDB,
|
||||
messageId: string
|
||||
): PinnedMessage | null {
|
||||
const [query, params] = sql`
|
||||
SELECT * FROM pinnedMessages
|
||||
WHERE messageId IS ${messageId}
|
||||
`;
|
||||
return db.prepare(query).get<PinnedMessage>(params) ?? null;
|
||||
}
|
||||
|
||||
function _insertPinnedMessage(
|
||||
db: WritableDB,
|
||||
pinnedMessageParams: PinnedMessageParams
|
||||
): PinnedMessage {
|
||||
@@ -30,17 +41,11 @@ export function createPinnedMessage(
|
||||
INSERT INTO pinnedMessages (
|
||||
conversationId,
|
||||
messageId,
|
||||
messageSentAt,
|
||||
messageSenderAci,
|
||||
pinnedByAci,
|
||||
pinnedAt,
|
||||
expiresAt
|
||||
) VALUES (
|
||||
${pinnedMessageParams.conversationId},
|
||||
${pinnedMessageParams.messageId},
|
||||
${pinnedMessageParams.messageSentAt},
|
||||
${pinnedMessageParams.messageSenderAci},
|
||||
${pinnedMessageParams.pinnedByAci},
|
||||
${pinnedMessageParams.pinnedAt},
|
||||
${pinnedMessageParams.expiresAt}
|
||||
)
|
||||
@@ -52,13 +57,10 @@ export function createPinnedMessage(
|
||||
return row;
|
||||
}
|
||||
|
||||
export function deletePinnedMessage(
|
||||
db: WritableDB,
|
||||
pinnedMessageId: PinnedMessageId
|
||||
): void {
|
||||
function _deletePinnedMessageById(db: WritableDB, id: PinnedMessageId): void {
|
||||
const [query, params] = sql`
|
||||
DELETE FROM pinnedMessages
|
||||
WHERE id = ${pinnedMessageId}
|
||||
WHERE id = ${id}
|
||||
`;
|
||||
const result = db.prepare(query).run(params);
|
||||
strictAssert(
|
||||
@@ -67,11 +69,106 @@ export function deletePinnedMessage(
|
||||
);
|
||||
}
|
||||
|
||||
function _truncatePinnedMessagesByConversationId(
|
||||
db: WritableDB,
|
||||
conversationId: string,
|
||||
pinnedMessagesLimit: number
|
||||
): ReadonlyArray<PinnedMessageId> {
|
||||
const [query, params] = sql`
|
||||
DELETE FROM pinnedMessages
|
||||
WHERE conversationId = ${conversationId}
|
||||
AND id NOT IN (
|
||||
SELECT id FROM pinnedMessages
|
||||
WHERE conversationId = ${conversationId}
|
||||
ORDER BY pinnedAt DESC
|
||||
LIMIT ${pinnedMessagesLimit}
|
||||
)
|
||||
RETURNING id
|
||||
`;
|
||||
|
||||
return db.prepare(query, { pluck: true }).all<PinnedMessageId>(params);
|
||||
}
|
||||
|
||||
export type AppendPinnedMessageChange = Readonly<{
|
||||
inserted: PinnedMessage;
|
||||
replaced: PinnedMessageId | null;
|
||||
}>;
|
||||
|
||||
export type AppendPinnedMessageResult = Readonly<{
|
||||
change: AppendPinnedMessageChange | null;
|
||||
// Note: The `inserted` pin may immediately be truncated
|
||||
truncated: ReadonlyArray<PinnedMessageId>;
|
||||
}>;
|
||||
|
||||
export function appendPinnedMessage(
|
||||
db: WritableDB,
|
||||
pinnedMessagesLimit: number,
|
||||
pinnedMessageParams: PinnedMessageParams
|
||||
): AppendPinnedMessageResult {
|
||||
return db.transaction(() => {
|
||||
const existing = _getPinnedMessageByMessageId(
|
||||
db,
|
||||
pinnedMessageParams.messageId
|
||||
);
|
||||
|
||||
let shouldInsertOrReplace: boolean;
|
||||
if (existing == null) {
|
||||
// Always insert if there's no existing
|
||||
shouldInsertOrReplace = true;
|
||||
} else if (pinnedMessageParams.pinnedAt > existing.pinnedAt) {
|
||||
// Only replace if the pin is newer
|
||||
shouldInsertOrReplace = true;
|
||||
} else {
|
||||
shouldInsertOrReplace = false;
|
||||
}
|
||||
|
||||
let change: AppendPinnedMessageChange | null = null;
|
||||
if (shouldInsertOrReplace) {
|
||||
let replaced: PinnedMessageId | null = null;
|
||||
|
||||
if (existing != null) {
|
||||
_deletePinnedMessageById(db, existing.id);
|
||||
replaced = existing.id;
|
||||
}
|
||||
|
||||
const inserted = _insertPinnedMessage(db, pinnedMessageParams);
|
||||
|
||||
change = { inserted, replaced };
|
||||
}
|
||||
|
||||
const truncated = _truncatePinnedMessagesByConversationId(
|
||||
db,
|
||||
pinnedMessageParams.conversationId,
|
||||
pinnedMessagesLimit
|
||||
);
|
||||
|
||||
return { change, truncated };
|
||||
})();
|
||||
}
|
||||
|
||||
export function deletePinnedMessageByMessageId(
|
||||
db: WritableDB,
|
||||
messageId: string
|
||||
): PinnedMessageId | null {
|
||||
const [query, params] = sql`
|
||||
DELETE FROM pinnedMessages
|
||||
WHERE messageId = ${messageId}
|
||||
RETURNING id
|
||||
`;
|
||||
|
||||
const result = db
|
||||
.prepare(query, { pluck: true })
|
||||
.get<PinnedMessageId>(params);
|
||||
|
||||
return result ?? null;
|
||||
}
|
||||
|
||||
export function getNextExpiringPinnedMessageAcrossConversations(
|
||||
db: ReadableDB
|
||||
): PinnedMessage | null {
|
||||
const [query, params] = sql`
|
||||
SELECT * FROM pinnedMessages
|
||||
WHERE expiresAt IS NOT null
|
||||
ORDER BY expiresAt ASC
|
||||
LIMIT 1
|
||||
`;
|
||||
|
||||
Reference in New Issue
Block a user