diff --git a/keyserver/src/updaters/thread-updaters.js b/keyserver/src/updaters/thread-updaters.js --- a/keyserver/src/updaters/thread-updaters.js +++ b/keyserver/src/updaters/thread-updaters.js @@ -23,6 +23,7 @@ type UpdateThreadRequest, type ServerThreadJoinRequest, type ThreadJoinResult, + type ToggleMessagePinRequest, threadPermissions, threadTypes, } from 'lib/types/thread-types.js'; @@ -854,6 +855,38 @@ await createUpdates(updateDatas); } +async function toggleMessagePinForThread( + viewer: Viewer, + request: ToggleMessagePinRequest, +): Promise { + const { messageID, action } = request; + + const threadQuery = SQL`SELECT thread FROM messages WHERE id = ${messageID}`; + const [threadResult] = await dbQuery(threadQuery); + const threadID = threadResult[0].thread.toString(); + + const hasPermission = await checkThreadPermission( + viewer, + threadID, + threadPermissions.MANAGE_PINS, + ); + + if (!hasPermission) { + throw new ServerError('invalid_credentials'); + } + + const pinnedValue = action === 'pin' ? 1 : 0; + const pinTimeValue = action === 'pin' ? Date.now() : null; + + const togglePinQuery = SQL` + UPDATE messages + SET pinned = ${pinnedValue}, pin_time = ${pinTimeValue} + WHERE id = ${messageID} AND thread = ${threadID} + `; + + await dbQuery(togglePinQuery); +} + export { updateRole, removeMembers, @@ -861,4 +894,5 @@ updateThread, joinThread, updateThreadMembers, + toggleMessagePinForThread, }; diff --git a/lib/types/thread-types.js b/lib/types/thread-types.js --- a/lib/types/thread-types.js +++ b/lib/types/thread-types.js @@ -488,6 +488,11 @@ +mostRecentNonLocalMessage: ?string, }; +export type ToggleMessagePinRequest = { + +messageID: string, + +action: 'pin' | 'unpin', +}; + // We can show a max of 3 sidebars inline underneath their parent in the chat // tab. If there are more, we show a button that opens a modal to see the rest export const maxReadSidebars = 3;