Page MenuHomePhabricator

D7148.id24001.diff
No OneTemporary

D7148.id24001.diff

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
@@ -1,5 +1,6 @@
// @flow
+import { contentStringForMediaArray } from 'lib/media/media-utils.js';
import { filteredThreadIDs } from 'lib/selectors/calendar-filter-selectors.js';
import {
threadHasAdminRole,
@@ -43,7 +44,10 @@
import { createUpdates } from '../creators/update-creator.js';
import { dbQuery, SQL } from '../database/database.js';
import { fetchEntryInfos } from '../fetchers/entry-fetchers.js';
-import { fetchMessageInfos } from '../fetchers/message-fetchers.js';
+import {
+ fetchMessageInfos,
+ fetchMessageInfoByID,
+} from '../fetchers/message-fetchers.js';
import {
fetchThreadInfos,
fetchServerThreadInfos,
@@ -875,6 +879,33 @@
}
await dbQuery(togglePinQuery);
+
+ const targetMessage = await fetchMessageInfoByID(viewer, messageID);
+ if (!targetMessage) {
+ throw new ServerError('invalid_parameters');
+ }
+
+ let pinnedContent;
+ if (
+ targetMessage.type === messageTypes.IMAGES ||
+ targetMessage.type === messageTypes.MULTIMEDIA
+ ) {
+ pinnedContent = contentStringForMediaArray(targetMessage.media);
+ } else {
+ pinnedContent = 'a message';
+ }
+
+ const messageData = {
+ type: messageTypes.TOGGLE_PIN,
+ threadID,
+ targetMessageID: messageID,
+ action,
+ pinnedContent,
+ creatorID: viewer.userID,
+ time: Date.now(),
+ };
+
+ await createMessages(viewer, [messageData]);
}
export {
diff --git a/lib/shared/messages/message-specs.js b/lib/shared/messages/message-specs.js
--- a/lib/shared/messages/message-specs.js
+++ b/lib/shared/messages/message-specs.js
@@ -18,6 +18,7 @@
import { restoreEntryMessageSpec } from './restore-entry-message-spec.js';
import { sidebarSourceMessageSpec } from './sidebar-source-message-spec.js';
import { textMessageSpec } from './text-message-spec.js';
+import { togglePinMessageSpec } from './toggle-pin-message-spec.js';
import { unsupportedMessageSpec } from './unsupported-message-spec.js';
import { updateRelationshipMessageSpec } from './update-relationship-message-spec.js';
import { messageTypes, type MessageType } from '../../types/message-types.js';
@@ -45,4 +46,5 @@
[messageTypes.SIDEBAR_SOURCE]: sidebarSourceMessageSpec,
[messageTypes.CREATE_SIDEBAR]: createSidebarMessageSpec,
[messageTypes.REACTION]: reactionMessageSpec,
+ [messageTypes.TOGGLE_PIN]: togglePinMessageSpec,
});
diff --git a/lib/shared/messages/toggle-pin-message-spec.js b/lib/shared/messages/toggle-pin-message-spec.js
new file mode 100644
--- /dev/null
+++ b/lib/shared/messages/toggle-pin-message-spec.js
@@ -0,0 +1,185 @@
+// @flow
+
+import invariant from 'invariant';
+
+import type { MessageSpec, RobotextParams } from './message-spec.js';
+import { joinResult, assertSingleMessageInfo } from './utils.js';
+import type { PlatformDetails } from '../../types/device-types';
+import { messageTypes } from '../../types/message-types.js';
+import type {
+ MessageInfo,
+ ClientDBMessageInfo,
+} from '../../types/message-types.js';
+import type {
+ TogglePinMessageData,
+ TogglePinMessageInfo,
+ RawTogglePinMessageInfo,
+} from '../../types/messages/toggle-pin.js';
+import type { RawUnsupportedMessageInfo } from '../../types/messages/unsupported';
+import type { NotifTexts } from '../../types/notif-types.js';
+import type { ThreadInfo } from '../../types/thread-types.js';
+import type { RelativeUserInfo } from '../../types/user-types.js';
+import { ET, type EntityText } from '../../utils/entity-text.js';
+import { hasMinCodeVersion } from '../version-utils.js';
+
+export const togglePinMessageSpec: MessageSpec<
+ TogglePinMessageData,
+ RawTogglePinMessageInfo,
+ TogglePinMessageInfo,
+> = Object.freeze({
+ messageContentForServerDB(
+ data: TogglePinMessageData | RawTogglePinMessageInfo,
+ ): string {
+ return JSON.stringify({
+ action: data.action,
+ pinnedContent: data.pinnedContent,
+ threadID: data.threadID,
+ targetMessageID: data.targetMessageID,
+ });
+ },
+
+ messageContentForClientDB(data: RawTogglePinMessageInfo): string {
+ return this.messageContentForServerDB(data);
+ },
+
+ rawMessageInfoFromServerDBRow(row: Object): RawTogglePinMessageInfo {
+ const content = JSON.parse(row.content);
+ return {
+ type: messageTypes.TOGGLE_PIN,
+ id: row.id.toString(),
+ threadID: row.threadID.toString(),
+ targetMessageID: content.targetMessageID.toString(),
+ action: content.action,
+ pinnedContent: content.pinnedContent,
+ time: row.time,
+ creatorID: row.creatorID.toString(),
+ };
+ },
+
+ rawMessageInfoFromClientDB(
+ clientDBMessageInfo: ClientDBMessageInfo,
+ ): RawTogglePinMessageInfo {
+ invariant(
+ clientDBMessageInfo.content !== undefined &&
+ clientDBMessageInfo.content !== null,
+ 'content must be defined for TogglePin',
+ );
+ const content = JSON.parse(clientDBMessageInfo.content);
+
+ const rawTogglePinMessageInfo: RawTogglePinMessageInfo = {
+ type: messageTypes.TOGGLE_PIN,
+ id: clientDBMessageInfo.id,
+ threadID: clientDBMessageInfo.thread,
+ targetMessageID: content.targetMessageID,
+ action: content.action,
+ pinnedContent: content.pinnedContent,
+ time: parseInt(clientDBMessageInfo.time),
+ creatorID: clientDBMessageInfo.user,
+ };
+ return rawTogglePinMessageInfo;
+ },
+
+ createMessageInfo(
+ rawMessageInfo: RawTogglePinMessageInfo,
+ creator: RelativeUserInfo,
+ ): TogglePinMessageInfo {
+ return {
+ type: messageTypes.TOGGLE_PIN,
+ id: rawMessageInfo.id,
+ threadID: rawMessageInfo.threadID,
+ targetMessageID: rawMessageInfo.targetMessageID,
+ action: rawMessageInfo.action,
+ pinnedContent: rawMessageInfo.pinnedContent,
+ creator,
+ time: rawMessageInfo.time,
+ };
+ },
+
+ rawMessageInfoFromMessageData(
+ messageData: TogglePinMessageData,
+ id: ?string,
+ ): RawTogglePinMessageInfo {
+ invariant(id, 'RawTogglePinMessageInfo needs id');
+ return { ...messageData, id };
+ },
+
+ robotext(
+ messageInfo: TogglePinMessageInfo,
+ params: RobotextParams,
+ ): EntityText {
+ const creator = ET.user({ userInfo: messageInfo.creator });
+ const action = messageInfo.action === 'pin' ? 'pinned' : 'unpinned';
+ const pinnedContent = messageInfo.pinnedContent;
+ const preposition = messageInfo.action === 'pin' ? 'in' : 'from';
+ return ET`${creator} ${action} ${pinnedContent} ${preposition} ${ET.thread({
+ display: 'alwaysDisplayShortName',
+ threadID: messageInfo.threadID,
+ threadType: params.threadInfo?.type,
+ parentThreadID: params.threadInfo?.parentThreadID,
+ })}`;
+ },
+
+ shimUnsupportedMessageInfo(
+ rawMessageInfo: RawTogglePinMessageInfo,
+ platformDetails: ?PlatformDetails,
+ ): RawTogglePinMessageInfo | RawUnsupportedMessageInfo {
+ // TODO: Change before landing
+ if (hasMinCodeVersion(platformDetails, 10000)) {
+ return rawMessageInfo;
+ }
+ const { id } = rawMessageInfo;
+ invariant(id !== null && id !== undefined, 'id should be set on server');
+
+ return {
+ type: messageTypes.UNSUPPORTED,
+ id,
+ threadID: rawMessageInfo.threadID,
+ creatorID: rawMessageInfo.creatorID,
+ time: rawMessageInfo.time,
+ robotext: 'toggled a message pin',
+ unsupportedMessageInfo: rawMessageInfo,
+ };
+ },
+
+ unshimMessageInfo(
+ unwrapped: RawTogglePinMessageInfo,
+ ): RawTogglePinMessageInfo {
+ return unwrapped;
+ },
+
+ async notificationTexts(
+ messageInfos: $ReadOnlyArray<MessageInfo>,
+ threadInfo: ThreadInfo,
+ ): Promise<NotifTexts> {
+ const messageInfo = assertSingleMessageInfo(messageInfos);
+ invariant(
+ messageInfo.type === messageTypes.TOGGLE_PIN,
+ 'messageInfo should be messageTypes.TOGGLE_PIN!',
+ );
+
+ const creator = ET.user({ userInfo: messageInfo.creator });
+ const body =
+ messageInfo.action === 'pin'
+ ? ET`${creator} pinned ${messageInfo.pinnedContent} in`
+ : ET`${creator} unpinned ${messageInfo.pinnedContent} from`;
+ const thread = ET.thread({ display: 'shortName', threadInfo });
+ const merged = ET`${body} ${thread}`;
+
+ return {
+ merged,
+ title: threadInfo.uiName,
+ body,
+ };
+ },
+
+ notificationCollapseKey(rawMessageInfo: RawTogglePinMessageInfo): string {
+ return joinResult(
+ rawMessageInfo.type,
+ rawMessageInfo.threadID,
+ rawMessageInfo.creatorID,
+ rawMessageInfo.targetMessageID,
+ );
+ },
+
+ generatesNotifs: async () => undefined,
+});
diff --git a/lib/types/message-types.js b/lib/types/message-types.js
--- a/lib/types/message-types.js
+++ b/lib/types/message-types.js
@@ -89,6 +89,11 @@
TextMessageData,
TextMessageInfo,
} from './messages/text.js';
+import type {
+ TogglePinMessageData,
+ TogglePinMessageInfo,
+ RawTogglePinMessageInfo,
+} from './messages/toggle-pin.js';
import type {
RawUnsupportedMessageInfo,
UnsupportedMessageInfo,
@@ -131,6 +136,7 @@
// Appears in the newly created sidebar
CREATE_SIDEBAR: 18,
REACTION: 19,
+ TOGGLE_PIN: 20,
});
export type MessageType = $Values<typeof messageTypes>;
export function assertMessageType(ourMessageType: number): MessageType {
@@ -154,7 +160,8 @@
ourMessageType === 16 ||
ourMessageType === 17 ||
ourMessageType === 18 ||
- ourMessageType === 19,
+ ourMessageType === 19 ||
+ ourMessageType === 20,
'number is not MessageType enum',
);
return ourMessageType;
@@ -245,7 +252,8 @@
| UpdateRelationshipMessageData
| SidebarSourceMessageData
| CreateSidebarMessageData
- | ReactionMessageData;
+ | ReactionMessageData
+ | TogglePinMessageData;
export type MultimediaMessageData = ImagesMessageData | MediaMessageData;
@@ -271,7 +279,8 @@
| RawRestoreEntryMessageInfo
| RawUpdateRelationshipMessageInfo
| RawCreateSidebarMessageInfo
- | RawUnsupportedMessageInfo;
+ | RawUnsupportedMessageInfo
+ | RawTogglePinMessageInfo;
export type RawSidebarSourceMessageInfo = {
...SidebarSourceMessageData,
id: string,
@@ -319,7 +328,8 @@
| RestoreEntryMessageInfo
| UnsupportedMessageInfo
| UpdateRelationshipMessageInfo
- | CreateSidebarMessageInfo;
+ | CreateSidebarMessageInfo
+ | TogglePinMessageInfo;
export type PreviewableMessageInfo =
| RobotextMessageInfo
| MultimediaMessageInfo
diff --git a/lib/types/messages/toggle-pin.js b/lib/types/messages/toggle-pin.js
new file mode 100644
--- /dev/null
+++ b/lib/types/messages/toggle-pin.js
@@ -0,0 +1,29 @@
+// @flow
+
+import type { RelativeUserInfo } from '../user-types.js';
+
+export type TogglePinMessageData = {
+ type: 20,
+ threadID: string,
+ targetMessageID: string,
+ action: 'pin' | 'unpin',
+ pinnedContent: string,
+ creatorID: string,
+ time: number,
+};
+
+export type RawTogglePinMessageInfo = {
+ ...TogglePinMessageData,
+ id: string,
+};
+
+export type TogglePinMessageInfo = {
+ type: 20,
+ id: string,
+ threadID: string,
+ targetMessageID: string,
+ action: 'pin' | 'unpin',
+ pinnedContent: string,
+ creator: RelativeUserInfo,
+ time: number,
+};

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 27, 7:43 PM (20 h, 56 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2591492
Default Alt Text
D7148.id24001.diff (11 KB)

Event Timeline