diff --git a/keyserver/src/fetchers/community-fetchers.js b/keyserver/src/fetchers/community-fetchers.js index 6c52e997a5..d7e29f66dd 100644 --- a/keyserver/src/fetchers/community-fetchers.js +++ b/keyserver/src/fetchers/community-fetchers.js @@ -5,6 +5,7 @@ import type { ServerCommunityInfoWithCommunityName, } from 'lib/types/community-types.js'; +import { fetchPrivilegedThreadInfos } from './thread-fetchers.js'; import { dbQuery, SQL, mergeAndConditions } from '../database/database.js'; import { Viewer } from '../session/viewer.js'; @@ -80,9 +81,9 @@ async function fetchCommunityFarcasterChannelTag( return communityInfo?.farcasterChannelID; } -async function fetchAllCommunityInfosWithNames(): Promise< - $ReadOnlyArray, -> { +async function fetchAllCommunityInfosWithNames( + viewer: Viewer, +): Promise<$ReadOnlyArray> { const query = SQL` SELECT c.id, t.name as communityName, c.farcaster_channel_id as farcasterChannelID @@ -92,11 +93,20 @@ async function fetchAllCommunityInfosWithNames(): Promise< const [result] = await dbQuery(query); - const communityInfos = result.map(row => ({ - id: row.id.toString(), - farcasterChannelID: row.farcasterChannelID, - communityName: row.communityName, - })); + const threadIDs = new Set(result.map(row => row.id.toString())); + + const threadInfosResult = await fetchPrivilegedThreadInfos(viewer, { + threadIDs, + }); + + const communityInfos = result.map( + (row): ServerCommunityInfoWithCommunityName => ({ + id: row.id.toString(), + farcasterChannelID: row.farcasterChannelID, + communityName: row.communityName, + threadInfo: threadInfosResult.threadInfos[row.id.toString()] ?? null, + }), + ); return communityInfos; } diff --git a/keyserver/src/responders/community-responders.js b/keyserver/src/responders/community-responders.js index dc8fde0211..17dfe5f35f 100644 --- a/keyserver/src/responders/community-responders.js +++ b/keyserver/src/responders/community-responders.js @@ -2,7 +2,7 @@ import type { FetchCommunityInfosResponse, - FetchAllCommunityInfosWithNamesResponse, + ServerFetchAllCommunityInfosWithNamesResponse, } from 'lib/types/community-types.js'; import { @@ -26,12 +26,13 @@ async function fetchCommunityInfosResponder( async function fetchAllCommunityInfosWithNamesResponder( viewer: Viewer, -): Promise { +): Promise { if (!viewer.loggedIn) { return { allCommunityInfosWithNames: [] }; } - const allCommunityInfosWithNames = await fetchAllCommunityInfosWithNames(); + const allCommunityInfosWithNames = + await fetchAllCommunityInfosWithNames(viewer); return { allCommunityInfosWithNames }; } diff --git a/keyserver/src/scripts/delete-all-fc-channel-tags.js b/keyserver/src/scripts/delete-all-fc-channel-tags.js index d09b689b1a..eb7d921571 100644 --- a/keyserver/src/scripts/delete-all-fc-channel-tags.js +++ b/keyserver/src/scripts/delete-all-fc-channel-tags.js @@ -10,7 +10,8 @@ async function deleteAllFCChannelTags() { const admin = await thisKeyserverAdmin(); const adminViewer = createScriptViewer(admin.id); - const allCommunityInfosWithNames = await fetchAllCommunityInfosWithNames(); + const allCommunityInfosWithNames = + await fetchAllCommunityInfosWithNames(adminViewer); const deleteFarcasterChannelTagPromises = allCommunityInfosWithNames .map(communityInfoWithName => { diff --git a/lib/actions/community-actions.js b/lib/actions/community-actions.js index ec19de1e34..636e412205 100644 --- a/lib/actions/community-actions.js +++ b/lib/actions/community-actions.js @@ -7,7 +7,7 @@ import type { CallKeyserverEndpoint } from '../keyserver-conn/keyserver-conn-typ import type { ServerCommunityInfo, FetchCommunityInfosResponse, - FetchAllCommunityInfosWithNamesResponse, + ClientFetchAllCommunityInfosWithNamesResponse, CreateOrUpdateFarcasterChannelTagRequest, CreateOrUpdateFarcasterChannelTagResponse, DeleteFarcasterChannelTagRequest, @@ -69,7 +69,7 @@ const fetchAllCommunityInfosWithNamesActionTypes = Object.freeze({ const fetchAllCommunityInfosWithNames = ( callSingleKeyserverEndpoint: CallSingleKeyserverEndpoint, - ): (() => Promise) => + ): (() => Promise) => () => callSingleKeyserverEndpoint('fetch_all_community_infos_with_names'); const createOrUpdateFarcasterChannelTagActionTypes = Object.freeze({ diff --git a/lib/types/community-types.js b/lib/types/community-types.js index 7b0d94f1bd..537f408dfb 100644 --- a/lib/types/community-types.js +++ b/lib/types/community-types.js @@ -3,8 +3,13 @@ import t, { type TInterface } from 'tcomb'; import type { RawMessageInfo } from './message-types.js'; -import type { ChangeThreadSettingsResult } from './thread-types.js'; +import type { ThinRawThreadInfo } from './minimally-encoded-thread-permissions-types.js'; +import type { + ChangeThreadSettingsResult, + LegacyThinRawThreadInfo, +} from './thread-types.js'; import type { ServerUpdateInfo } from './update-types.js'; +import { thinRawThreadInfoValidator } from '../permissions/minimally-encoded-raw-thread-info-validators.js'; import { tID, tShape } from '../utils/validation-utils.js'; export type CommunityInfo = { @@ -36,23 +41,35 @@ export const serverCommunityInfoValidator: TInterface = export type ServerCommunityInfoWithCommunityName = $ReadOnly<{ ...ServerCommunityInfo, +communityName: string, + +threadInfo: LegacyThinRawThreadInfo | ThinRawThreadInfo | null, }>; -export const serverCommunityInfoWithCommunityNameValidator: TInterface = - tShape({ +export type ClientCommunityInfoWithCommunityName = $ReadOnly<{ + ...ServerCommunityInfo, + +communityName: string, + +threadInfo: ThinRawThreadInfo | null, +}>; + +export const clientCommunityInfoWithCommunityNameValidator: TInterface = + tShape({ id: tID, farcasterChannelID: t.maybe(t.String), communityName: t.String, + threadInfo: t.maybe(thinRawThreadInfoValidator), }); export type FetchCommunityInfosResponse = { +communityInfos: $ReadOnlyArray, }; -export type FetchAllCommunityInfosWithNamesResponse = { +export type ServerFetchAllCommunityInfosWithNamesResponse = { +allCommunityInfosWithNames: $ReadOnlyArray, }; +export type ClientFetchAllCommunityInfosWithNamesResponse = { + +allCommunityInfosWithNames: $ReadOnlyArray, +}; + export type CreateOrUpdateFarcasterChannelTagRequest = { +commCommunityID: string, +farcasterChannelID: string, diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js index 032c519079..ee4a0f5567 100644 --- a/lib/types/redux-types.js +++ b/lib/types/redux-types.js @@ -34,7 +34,7 @@ import type { CommunityStore, AddCommunityPayload, FetchCommunityInfosResponse, - FetchAllCommunityInfosWithNamesResponse, + ClientFetchAllCommunityInfosWithNamesResponse, CreateOrUpdateFarcasterChannelTagResponse, DeleteFarcasterChannelTagPayload, } from './community-types.js'; @@ -1474,7 +1474,7 @@ export type BaseAction = $ReadOnly<{ } | { +type: 'FETCH_ALL_COMMUNITY_INFOS_WITH_NAMES_SUCCESS', - +payload: FetchAllCommunityInfosWithNamesResponse, + +payload: ClientFetchAllCommunityInfosWithNamesResponse, +loadingInfo: LoadingInfo, } | { diff --git a/lib/types/validators/community-validators.js b/lib/types/validators/community-validators.js index 2c7507f4bf..2ca39cf56c 100644 --- a/lib/types/validators/community-validators.js +++ b/lib/types/validators/community-validators.js @@ -5,9 +5,9 @@ import t, { type TInterface } from 'tcomb'; import { tShape } from '../../utils/validation-utils.js'; import { serverCommunityInfoValidator, - serverCommunityInfoWithCommunityNameValidator, + clientCommunityInfoWithCommunityNameValidator, type FetchCommunityInfosResponse, - type FetchAllCommunityInfosWithNamesResponse, + type ClientFetchAllCommunityInfosWithNamesResponse, } from '../community-types.js'; const fetchCommunityInfosResponseValidator: TInterface = @@ -15,10 +15,10 @@ const fetchCommunityInfosResponseValidator: TInterface = +const fetchAllCommunityInfosWithNamesResponseValidator: TInterface = tShape({ allCommunityInfosWithNames: t.list( - serverCommunityInfoWithCommunityNameValidator, + clientCommunityInfoWithCommunityNameValidator, ), });