mirror of
https://github.com/signalapp/Signal-Desktop.git
synced 2026-05-01 22:01:49 +01:00
Integrate pinned messages bar/panel
This commit is contained in:
@@ -69,12 +69,14 @@ import type {
|
||||
PinnedMessage,
|
||||
PinnedMessageId,
|
||||
PinnedMessageParams,
|
||||
PinnedMessageRenderData,
|
||||
} from '../types/PinnedMessage.std.js';
|
||||
import type { AppendPinnedMessageResult } from './server/pinnedMessages.std.js';
|
||||
import type {
|
||||
RemoteMegaphoneId,
|
||||
RemoteMegaphoneType,
|
||||
} from '../types/Megaphone.std.js';
|
||||
import { QueryFragment, sqlJoin } from './util.std.js';
|
||||
|
||||
export type ReadableDB = Database & { __readable_db: never };
|
||||
export type WritableDB = ReadableDB & { __writable_db: never };
|
||||
@@ -191,6 +193,12 @@ export const MESSAGE_COLUMNS = [
|
||||
...MESSAGE_NON_PRIMARY_KEY_COLUMNS,
|
||||
] as const;
|
||||
|
||||
export const MESSAGE_COLUMNS_FRAGMENTS = MESSAGE_COLUMNS.map(
|
||||
column => new QueryFragment(column, [])
|
||||
);
|
||||
|
||||
export const MESSAGE_COLUMNS_SELECT = sqlJoin(MESSAGE_COLUMNS_FRAGMENTS);
|
||||
|
||||
export type MessageTypeUnhydrated = {
|
||||
json: string;
|
||||
|
||||
@@ -980,7 +988,7 @@ type ReadableInterface = {
|
||||
|
||||
getPinnedMessagesForConversation: (
|
||||
conversationId: string
|
||||
) => ReadonlyArray<PinnedMessage>;
|
||||
) => ReadonlyArray<PinnedMessageRenderData>;
|
||||
getNextExpiringPinnedMessageAcrossConversations: () => PinnedMessage | null;
|
||||
|
||||
getMessagesNeedingUpgrade: (
|
||||
|
||||
@@ -49,7 +49,7 @@ import { isNormalNumber } from '../util/isNormalNumber.std.js';
|
||||
import { isNotNil } from '../util/isNotNil.std.js';
|
||||
import { parseIntOrThrow } from '../util/parseIntOrThrow.std.js';
|
||||
import { updateSchema } from './migrations/index.node.js';
|
||||
import type { JSONRows } from './util.std.js';
|
||||
import type { JSONRows, QueryFragment } from './util.std.js';
|
||||
import {
|
||||
batchMultiVarQuery,
|
||||
bulkAdd,
|
||||
@@ -68,7 +68,6 @@ import {
|
||||
sqlConstant,
|
||||
sqlFragment,
|
||||
sqlJoin,
|
||||
QueryFragment,
|
||||
convertOptionalBooleanToInteger,
|
||||
} from './util.std.js';
|
||||
import {
|
||||
@@ -199,6 +198,8 @@ import type {
|
||||
import {
|
||||
AttachmentDownloadSource,
|
||||
MESSAGE_COLUMNS,
|
||||
MESSAGE_COLUMNS_FRAGMENTS,
|
||||
MESSAGE_COLUMNS_SELECT,
|
||||
MESSAGE_ATTACHMENT_COLUMNS,
|
||||
MESSAGE_NON_PRIMARY_KEY_COLUMNS,
|
||||
} from './Interface.std.js';
|
||||
@@ -783,10 +784,6 @@ export const DataWriter: ServerWritableInterface = {
|
||||
runCorruptionChecks,
|
||||
};
|
||||
|
||||
const MESSAGE_COLUMNS_FRAGMENTS = MESSAGE_COLUMNS.map(
|
||||
column => new QueryFragment(column, [])
|
||||
);
|
||||
|
||||
function rowToConversation(row: ConversationRow): ConversationType {
|
||||
const { expireTimerVersion } = row;
|
||||
const parsedJson = JSON.parse(row.json);
|
||||
@@ -3534,7 +3531,7 @@ function getUnreadReactionsAndMarkRead(
|
||||
return db
|
||||
.prepare(
|
||||
`
|
||||
UPDATE reactions
|
||||
UPDATE reactions
|
||||
INDEXED BY reactions_unread
|
||||
SET unread = 0
|
||||
WHERE
|
||||
@@ -3782,7 +3779,7 @@ function getRecentStoryReplies(
|
||||
|
||||
const createQuery = (timeFilter: QueryFragment): QueryFragment => sqlFragment`
|
||||
SELECT
|
||||
${sqlJoin(MESSAGE_COLUMNS_FRAGMENTS)}
|
||||
${MESSAGE_COLUMNS_SELECT}
|
||||
FROM messages
|
||||
WHERE
|
||||
(${messageId ?? null} IS NULL OR id IS NOT ${messageId ?? null}) AND
|
||||
|
||||
@@ -5,21 +5,65 @@ import type {
|
||||
PinnedMessage,
|
||||
PinnedMessageId,
|
||||
PinnedMessageParams,
|
||||
PinnedMessageRenderData,
|
||||
} from '../../types/PinnedMessage.std.js';
|
||||
import { strictAssert } from '../../util/assert.std.js';
|
||||
import type { ReadableDB, WritableDB } from '../Interface.std.js';
|
||||
import { hydrateMessage } from '../hydration.std.js';
|
||||
import type {
|
||||
MessageTypeUnhydrated,
|
||||
MessageType,
|
||||
ReadableDB,
|
||||
WritableDB,
|
||||
} from '../Interface.std.js';
|
||||
import { sql } from '../util.std.js';
|
||||
|
||||
function _getMessageById(
|
||||
db: ReadableDB,
|
||||
messageId: string
|
||||
): MessageType | null {
|
||||
const [query, params] = sql`
|
||||
SELECT * FROM messages
|
||||
WHERE id = ${messageId}
|
||||
`;
|
||||
|
||||
const row = db.prepare(query).get<MessageTypeUnhydrated>(params);
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return hydrateMessage(db, row);
|
||||
}
|
||||
|
||||
function _getPinnedMessageRenderData(
|
||||
db: ReadableDB,
|
||||
pinnedMessage: PinnedMessage
|
||||
): PinnedMessageRenderData {
|
||||
const message = _getMessageById(db, pinnedMessage.messageId);
|
||||
strictAssert(
|
||||
message != null,
|
||||
`Missing message ${pinnedMessage.messageId} for pinned message ${pinnedMessage.id}`
|
||||
);
|
||||
return { pinnedMessage, message };
|
||||
}
|
||||
|
||||
export function getPinnedMessagesForConversation(
|
||||
db: ReadableDB,
|
||||
conversationId: string
|
||||
): ReadonlyArray<PinnedMessage> {
|
||||
const [query, params] = sql`
|
||||
SELECT * FROM pinnedMessages
|
||||
WHERE conversationId = ${conversationId}
|
||||
ORDER BY pinnedAt DESC
|
||||
`;
|
||||
return db.prepare(query).all<PinnedMessage>(params);
|
||||
): ReadonlyArray<PinnedMessageRenderData> {
|
||||
return db.transaction(() => {
|
||||
const [query, params] = sql`
|
||||
SELECT * FROM pinnedMessages
|
||||
WHERE conversationId = ${conversationId}
|
||||
ORDER BY pinnedAt DESC
|
||||
`;
|
||||
|
||||
return db
|
||||
.prepare(query)
|
||||
.all<PinnedMessage>(params)
|
||||
.map(pinnedMessage => {
|
||||
return _getPinnedMessageRenderData(db, pinnedMessage);
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
||||
function _getPinnedMessageByMessageId(
|
||||
|
||||
Reference in New Issue
Block a user