diff --git a/src/lib/reddit/bot.ts b/src/lib/reddit/bot.ts index e74b305..78da2a5 100644 --- a/src/lib/reddit/bot.ts +++ b/src/lib/reddit/bot.ts @@ -387,9 +387,26 @@ export async function updateCommunity( avatarBlob = await client.uploadBlob(opts.avatar.bytes, opts.avatar.mimeType); } + // When the access mode changes, the pinned welcome post needs to + // be replaced — its text says either "Everyone can submit posts" + // or "People from this list can submit posts" with a link to the + // specific list, so changing `whoCanSubmit` or the `listUri` makes + // the old post stale. We create the replacement BEFORE touching + // the profile so we have the new `{uri, cid}` to pin. + let newPinnedPost: { uri: string; cid: string } | null = null; + if (opts.whoCanSubmit !== undefined) { + const shortHandle = row.handle.split('.')[0]; + newPinnedPost = await createWelcomePost(client, shortHandle, { + whoCanSubmit: opts.whoCanSubmit, + listUri: opts.listUri ?? null + }); + } + // Merge into the existing profile record. We read it first so we // don't clobber fields we don't touch (displayName etc.). - if (avatarBlob || opts.description !== undefined) { + const touchProfile = + !!avatarBlob || opts.description !== undefined || newPinnedPost !== null; + if (touchProfile) { try { const existing = await getRecord( row.pds, @@ -417,6 +434,25 @@ export async function updateCommunity( } next.description = full; } + if (newPinnedPost) { + // Delete the old pinned post before swapping in the new + // one. Best-effort — if the record is already gone or the + // PDS rejects us, we still update the profile pin. + const oldPinned = baseValue.pinnedPost as + | { uri?: string } + | undefined; + if (oldPinned?.uri) { + const parsed = parseCommunityRecordUri(oldPinned.uri); + if (parsed) { + try { + await client.deleteRecord(parsed.collection, parsed.rkey); + } catch { + /* old post might already be gone */ + } + } + } + next.pinnedPost = newPinnedPost; + } await client.putRecord('app.bsky.actor.profile', 'self', next); } catch (e) { diff --git a/src/lib/reddit/server/communities.remote.ts b/src/lib/reddit/server/communities.remote.ts index 20f2b05..8377e11 100644 --- a/src/lib/reddit/server/communities.remote.ts +++ b/src/lib/reddit/server/communities.remote.ts @@ -370,9 +370,13 @@ export const editCommunity = command( } // Parse + normalize the optional allowlist URL into a canonical - // at-URI, same as the register flow. + // at-URI, same as the register flow. Process the list URL + // whenever it's provided — not just when `whoCanSubmit` itself + // changes — so that switching to a different list while staying + // in 'list' mode actually takes effect. let listUri: string | null | undefined; - if (input.whoCanSubmit === 'list') { + const effectiveWhoCanSubmit = input.whoCanSubmit ?? config.whoCanSubmit; + if (effectiveWhoCanSubmit === 'list' && input.listUrl !== undefined) { if (!input.listUrl?.trim()) { error(400, 'List URL is required when "members of a list" is selected'); }