Page MenuHomePhabricator

D7211.id24887.diff
No OneTemporary

D7211.id24887.diff

diff --git a/keyserver/src/fetchers/thread-fetchers.js b/keyserver/src/fetchers/thread-fetchers.js
--- a/keyserver/src/fetchers/thread-fetchers.js
+++ b/keyserver/src/fetchers/thread-fetchers.js
@@ -36,12 +36,13 @@
`.append(whereClause);
const threadsQuery = SQL`
- SELECT t.id, t.name, t.parent_thread_id, t.containing_thread_id,
- t.community, t.depth, t.color, t.description, t.type, t.creation_time,
- t.source_message, t.replies_count, t.avatar, m.user, m.role, m.permissions,
- m.subscription, m.last_read_message < m.last_message AS unread, m.sender
- FROM threads t
- LEFT JOIN memberships m ON m.thread = t.id AND m.role >= 0
+ SELECT t.id, t.name, t.parent_thread_id, t.containing_thread_id,
+ t.community, t.depth, t.color, t.description, t.type, t.creation_time,
+ t.source_message, t.replies_count, t.avatar, t.pinned_count, m.user,
+ m.role, m.permissions, m.subscription,
+ m.last_read_message < m.last_message AS unread, m.sender
+ FROM threads t
+ LEFT JOIN memberships m ON m.thread = t.id AND m.role >= 0
`
.append(whereClause)
.append(SQL` ORDER BY m.user ASC`);
@@ -74,6 +75,7 @@
members: [],
roles: {},
repliesCount: threadsRow.replies_count,
+ pinnedCount: threadsRow.pinned_count,
};
if (threadsRow.avatar) {
threadInfos[threadID] = {
@@ -160,6 +162,10 @@
viewer.platformDetails,
104,
);
+ const hasCodeVersionBelow209 = !hasMinCodeVersion(
+ viewer.platformDetails,
+ 209,
+ );
const threadInfos = {};
for (const threadID in serverResult.threadInfos) {
const serverThreadInfo = serverResult.threadInfos[threadID];
@@ -172,6 +178,7 @@
shimThreadTypes: hasCodeVersionBelow87 ? shimCommunityRoot : null,
hideThreadStructure: hasCodeVersionBelow102,
filterDetailedThreadEditPermissions: hasCodeVersionBelow104,
+ excludePinInfo: hasCodeVersionBelow209,
},
);
if (threadInfo) {
diff --git a/lib/shared/thread-utils.js b/lib/shared/thread-utils.js
--- a/lib/shared/thread-utils.js
+++ b/lib/shared/thread-utils.js
@@ -376,6 +376,7 @@
},
repliesCount: 0,
sourceMessageID,
+ pinnedCount: 0,
};
const userInfos = {};
@@ -699,6 +700,7 @@
+[inType: ThreadType]: ThreadType,
},
+filterDetailedThreadEditPermissions?: boolean,
+ +excludePinInfo?: boolean,
};
function rawThreadInfoFromServerThreadInfo(
serverThreadInfo: ServerThreadInfo,
@@ -711,14 +713,16 @@
const shimThreadTypes = options?.shimThreadTypes;
const filterDetailedThreadEditPermissions =
options?.filterDetailedThreadEditPermissions;
+ const excludePinInfo = options?.excludePinInfo;
const filterThreadPermissions = _omitBy(
(v, k) =>
- filterDetailedThreadEditPermissions &&
- [
- threadPermissions.EDIT_THREAD_COLOR,
- threadPermissions.EDIT_THREAD_DESCRIPTION,
- ].includes(k),
+ (filterDetailedThreadEditPermissions &&
+ [
+ threadPermissions.EDIT_THREAD_COLOR,
+ threadPermissions.EDIT_THREAD_DESCRIPTION,
+ ].includes(k)) ||
+ (excludePinInfo && [threadPermissions.MANAGE_PINS].includes(k)),
);
const members = [];
@@ -826,6 +830,12 @@
visibilityRules: rawThreadInfo.type,
};
}
+ if (!excludePinInfo) {
+ return {
+ ...rawThreadInfo,
+ pinnedCount: serverThreadInfo.pinnedCount,
+ };
+ }
return rawThreadInfo;
}
@@ -873,7 +883,7 @@
...threadInfo,
uiName: threadUIName(threadInfo),
};
- const { sourceMessageID, avatar } = rawThreadInfo;
+ const { sourceMessageID, avatar, pinnedCount } = rawThreadInfo;
if (sourceMessageID) {
threadInfo = { ...threadInfo, sourceMessageID };
}
@@ -889,6 +899,11 @@
avatar: getUserAvatarForThread(rawThreadInfo, viewerID, userInfos),
};
}
+
+ if (pinnedCount) {
+ threadInfo = { ...threadInfo, pinnedCount };
+ }
+
return threadInfo;
}
diff --git a/lib/shared/unshim-utils.js b/lib/shared/unshim-utils.js
--- a/lib/shared/unshim-utils.js
+++ b/lib/shared/unshim-utils.js
@@ -44,6 +44,7 @@
messageTypes.SIDEBAR_SOURCE,
messageTypes.MULTIMEDIA,
messageTypes.REACTION,
+ messageTypes.TOGGLE_PIN,
]);
function unshimMessageInfos(
messageInfos: $ReadOnlyArray<RawMessageInfo>,
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
@@ -217,6 +217,7 @@
+currentUser: ThreadCurrentUserInfo,
+sourceMessageID?: string,
+repliesCount: number,
+ +pinnedCount?: number,
};
export type ThreadInfo = {
@@ -236,6 +237,7 @@
+currentUser: ThreadCurrentUserInfo,
+sourceMessageID?: string,
+repliesCount: number,
+ +pinnedCount?: number,
};
export type ResolvedThreadInfo = {
@@ -255,6 +257,7 @@
+currentUser: ThreadCurrentUserInfo,
+sourceMessageID?: string,
+repliesCount: number,
+ +pinnedCount?: number,
};
export type ServerMemberInfo = {
@@ -282,6 +285,7 @@
+roles: { [id: string]: RoleInfo },
+sourceMessageID?: string,
+repliesCount: number,
+ +pinnedCount: number,
};
export type ThreadStore = {
@@ -323,6 +327,7 @@
+currentUser: string,
+sourceMessageID?: string,
+repliesCount: number,
+ +pinnedCount?: number,
};
export type ClientDBReplaceThreadOperation = {
diff --git a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
--- a/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
+++ b/native/cpp/CommonCpp/NativeModules/CommCoreModule.cpp
@@ -255,6 +255,7 @@
? jsi::String::createFromUtf8(rt, *thread.source_message_id)
: jsi::Value::null());
jsiThread.setProperty(rt, "repliesCount", thread.replies_count);
+ jsiThread.setProperty(rt, "pinnedCount", thread.pinned_count);
if (thread.avatar) {
auto avatar = jsi::String::createFromUtf8(rt, *thread.avatar);
@@ -643,6 +644,10 @@
? std::make_unique<std::string>(maybeAvatar.asString(rt).utf8(rt))
: nullptr;
+ jsi::Value maybePinnedCount = threadObj.getProperty(rt, "pinnedCount");
+ int pinnedCount = maybePinnedCount.isNumber()
+ ? std::lround(maybePinnedCount.asNumber())
+ : 0;
Thread thread{
threadID,
type,
@@ -658,7 +663,8 @@
currentUser,
std::move(sourceMessageID),
repliesCount,
- std::move(avatar)};
+ std::move(avatar),
+ pinnedCount};
threadStoreOps.push_back(
std::make_unique<ReplaceThreadOperation>(std::move(thread)));
diff --git a/native/redux/persist.js b/native/redux/persist.js
--- a/native/redux/persist.js
+++ b/native/redux/persist.js
@@ -13,7 +13,10 @@
getContainingThreadID,
getCommunity,
} from 'lib/shared/thread-utils.js';
-import { DEPRECATED_unshimMessageStore } from 'lib/shared/unshim-utils.js';
+import {
+ DEPRECATED_unshimMessageStore,
+ unshimFunc,
+} from 'lib/shared/unshim-utils.js';
import { defaultEnabledApps } from 'lib/types/enabled-apps.js';
import { defaultCalendarFilters } from 'lib/types/filter-types.js';
import {
@@ -23,9 +26,20 @@
type ClientDBMessageStoreOperation,
} from 'lib/types/message-types.js';
import { defaultConnectionInfo } from 'lib/types/socket-types.js';
-import { translateRawMessageInfoToClientDBMessageInfo } from 'lib/utils/message-ops-utils.js';
+import type {
+ ClientDBThreadStoreOperation,
+ ClientDBThreadInfo,
+} from 'lib/types/thread-types.js';
+import {
+ translateClientDBMessageInfoToRawMessageInfo,
+ translateRawMessageInfoToClientDBMessageInfo,
+} from 'lib/utils/message-ops-utils.js';
import { defaultNotifPermissionAlertInfo } from 'lib/utils/push-alerts.js';
-import { convertThreadStoreOperationsToClientDBOperations } from 'lib/utils/thread-ops-utils.js';
+import {
+ convertClientDBThreadInfoToRawThreadInfo,
+ convertRawThreadInfoToClientDBThreadInfo,
+ convertThreadStoreOperationsToClientDBOperations,
+} from 'lib/utils/thread-ops-utils.js';
import { migrateThreadStoreForEditThreadPermissions } from './edit-thread-permission-migration.js';
import type { AppState } from './state-types.js';
@@ -391,6 +405,85 @@
return stateSansThreadIDsToNotifIDs;
},
[35]: (state: AppState) => unshimClientDB(state, [messageTypes.MULTIMEDIA]),
+ [36]: (state: AppState) => {
+ // 1. Get threads and messages from SQLite `threads` and `messages` tables.
+ const clientDBThreadInfos = commCoreModule.getAllThreadsSync();
+ const clientDBMessageInfos = commCoreModule.getAllMessagesSync();
+
+ // 2. Translate `ClientDBThreadInfo`s to `RawThreadInfo`s and
+ // `ClientDBMessageInfo`s to `RawMessageInfo`s.
+ const rawThreadInfos = clientDBThreadInfos.map(
+ convertClientDBThreadInfoToRawThreadInfo,
+ );
+ const rawMessageInfos = clientDBMessageInfos.map(
+ translateClientDBMessageInfoToRawMessageInfo,
+ );
+
+ // 3. Unshim translated `RawMessageInfos` to get the TOGGLE_PIN messages
+ const unshimmedRawMessageInfos = rawMessageInfos.map(messageInfo =>
+ unshimFunc(messageInfo, new Set([messageTypes.TOGGLE_PIN])),
+ );
+
+ // 4. Filter out non-TOGGLE_PIN messages
+ const filteredRawMessageInfos = unshimmedRawMessageInfos.filter(
+ messageInfo => messageInfo.type === messageTypes.TOGGLE_PIN,
+ );
+
+ // 5. We want only the last TOGGLE_PIN message for each message ID,
+ // so 'pin', 'unpin', 'pin' don't count as 3 pins, but only 1.
+ const lastMessageIDToRawMessageInfoMap = new Map();
+ for (const messageInfo of filteredRawMessageInfos) {
+ const { targetMessageID } = messageInfo;
+ lastMessageIDToRawMessageInfoMap.set(targetMessageID, messageInfo);
+ }
+ const lastMessageIDToRawMessageInfos = Array.from(
+ lastMessageIDToRawMessageInfoMap.values(),
+ );
+
+ // 6. Create a Map of threadIDs to pinnedCount
+ const threadIDsToPinnedCount = new Map();
+ for (const messageInfo of lastMessageIDToRawMessageInfos) {
+ const { threadID, type } = messageInfo;
+ if (type === messageTypes.TOGGLE_PIN) {
+ const pinnedCount = threadIDsToPinnedCount.get(threadID) || 0;
+ threadIDsToPinnedCount.set(threadID, pinnedCount + 1);
+ }
+ }
+
+ // 7. Include a pinnedCount for each rawThreadInfo
+ const rawThreadInfosWithPinnedCount = rawThreadInfos.map(threadInfo => ({
+ ...threadInfo,
+ pinnedCount: threadIDsToPinnedCount.get(threadInfo.id) || 0,
+ }));
+
+ // 8. Translate `RawThreadInfo`s to `ClientDBThreadInfo`s.
+ const convertedClientDBThreadInfos = rawThreadInfosWithPinnedCount.map(
+ convertRawThreadInfoToClientDBThreadInfo,
+ );
+
+ // 9. Construct `ClientDBThreadStoreOperation`s to clear SQLite `threads`
+ // table and repopulate with `ClientDBThreadInfo`s.
+ const operations: $ReadOnlyArray<ClientDBThreadStoreOperation> = [
+ {
+ type: 'remove_all',
+ },
+ ...convertedClientDBThreadInfos.map((thread: ClientDBThreadInfo) => ({
+ type: 'replace',
+ payload: thread,
+ })),
+ ];
+
+ // 10. Try processing `ClientDBThreadStoreOperation`s and log out if
+ // `processThreadStoreOperationsSync(...)` throws an exception.
+ try {
+ commCoreModule.processThreadStoreOperationsSync(operations);
+ } catch (exception) {
+ console.log(exception);
+ return { ...state, cookie: null };
+ }
+
+ return state;
+ },
};
// After migration 31, we'll no longer want to persist `messageStore.messages`
@@ -471,7 +564,7 @@
'storeLoaded',
],
debug: __DEV__,
- version: 35,
+ version: 36,
transforms: [messageStoreMessagesBlocklistTransform],
migrate: (createMigrate(migrations, { debug: __DEV__ }): any),
timeout: ((__DEV__ ? 0 : undefined): number | void),

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 24, 11:48 PM (20 h, 44 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2577721
Default Alt Text
D7211.id24887.diff (11 KB)

Event Timeline