diff --git a/keyserver/src/fetchers/community-fetchers.js b/keyserver/src/fetchers/community-fetchers.js --- a/keyserver/src/fetchers/community-fetchers.js +++ b/keyserver/src/fetchers/community-fetchers.js @@ -5,6 +5,7 @@ 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 @@ 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 @@ 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 --- 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 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 --- a/keyserver/src/scripts/delete-all-fc-channel-tags.js +++ b/keyserver/src/scripts/delete-all-fc-channel-tags.js @@ -10,7 +10,8 @@ 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 --- a/lib/actions/community-actions.js +++ b/lib/actions/community-actions.js @@ -7,7 +7,7 @@ import type { ServerCommunityInfo, FetchCommunityInfosResponse, - FetchAllCommunityInfosWithNamesResponse, + ClientFetchAllCommunityInfosWithNamesResponse, CreateOrUpdateFarcasterChannelTagRequest, CreateOrUpdateFarcasterChannelTagResponse, DeleteFarcasterChannelTagRequest, @@ -69,7 +69,7 @@ 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 --- 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 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 --- a/lib/types/redux-types.js +++ b/lib/types/redux-types.js @@ -34,7 +34,7 @@ CommunityStore, AddCommunityPayload, FetchCommunityInfosResponse, - FetchAllCommunityInfosWithNamesResponse, + ClientFetchAllCommunityInfosWithNamesResponse, CreateOrUpdateFarcasterChannelTagResponse, DeleteFarcasterChannelTagPayload, } from './community-types.js'; @@ -1474,7 +1474,7 @@ } | { +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 --- a/lib/types/validators/community-validators.js +++ b/lib/types/validators/community-validators.js @@ -5,9 +5,9 @@ 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 @@ communityInfos: t.list(serverCommunityInfoValidator), }); -const fetchAllCommunityInfosWithNamesResponseValidator: TInterface = +const fetchAllCommunityInfosWithNamesResponseValidator: TInterface = tShape({ allCommunityInfosWithNames: t.list( - serverCommunityInfoWithCommunityNameValidator, + clientCommunityInfoWithCommunityNameValidator, ), });