Mirror — see github.com/blacksky-algorithms/blacksky.community
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix assembly embed: hide statements when auth required, support anon votes

Two fixes:
- Auth-required conversations no longer show statement text to
unauthenticated users, just the sign-in button
- Anonymous voting works when conversation doesn't require auth
(no longer silently fails when user isn't logged into blacksky.community)

+30 -26
+30 -26
src/components/Post/Embed/ExternalEmbed/AssemblyEmbed.tsx
··· 140 140 141 141 const handleVote = useCallback( 142 142 async (value: -1 | 0 | 1) => { 143 - if (!statement || voting || !agent.session) return 143 + if (!statement || voting) return 144 144 setVoting(true) 145 145 setError(null) 146 146 147 147 try { 148 - // 1. Create signed vote record in user's repo. 148 + let voteAtUri: string | undefined 149 + 150 + // If authenticated, create a signed vote record in user's repo. 149 151 // This IS the authentication — only the DID owner can create 150 152 // records in their repo. The PDS validates the signing key. 151 - const createResult = await agent.com.atproto.repo.createRecord({ 152 - repo: agent.assertDid, 153 - collection: 'community.blacksky.assembly.vote', 154 - record: { 155 - $type: 'community.blacksky.assembly.vote', 156 - subject: { 157 - uri: statement.at_uri || '', 158 - cid: statement.at_cid || '', 153 + if (agent.session) { 154 + const createResult = await agent.com.atproto.repo.createRecord({ 155 + repo: agent.assertDid, 156 + collection: 'community.blacksky.assembly.vote', 157 + record: { 158 + $type: 'community.blacksky.assembly.vote', 159 + subject: { 160 + uri: statement.at_uri || '', 161 + cid: statement.at_cid || '', 162 + }, 163 + value, 164 + createdAt: new Date().toISOString(), 159 165 }, 160 - value, 161 - createdAt: new Date().toISOString(), 162 - }, 163 - }) 166 + }) 167 + voteAtUri = createResult.data.uri 168 + } 164 169 165 - // 2. Submit the AT URI to assembly's verified vote endpoint. 166 - // The server fetches the record from the user's PDS to verify 167 - // the DID owner actually created it — no impersonation possible. 170 + // Submit to assembly's verified vote endpoint. 171 + // If authenticated: server fetches the record from user's PDS to verify. 172 + // If anonymous: server accepts the vote directly (conversation allows it). 168 173 const voteResp = await fetch(`${ASSEMBLY_API}/embed/vote`, { 169 174 method: 'POST', 170 175 headers: {'Content-Type': 'application/json'}, ··· 172 177 conversation_id: conversationId, 173 178 tid: statement.tid, 174 179 vote: value, 175 - vote_at_uri: createResult.data.uri, 180 + ...(voteAtUri ? {vote_at_uri: voteAtUri} : {}), 176 181 }), 177 182 }) 178 183 179 184 if (!voteResp.ok) { 180 - throw new Error('Vote submission failed') 185 + const errBody = await voteResp.text() 186 + if (errBody.includes('polis_err_post_votes_social_needed')) { 187 + setError('Sign in required to vote.') 188 + } else { 189 + throw new Error('Vote submission failed') 190 + } 191 + return 181 192 } 182 193 183 194 const voteResult = (await voteResp.json()) as VoteResponse ··· 296 307 topic={data.conversation.topic} 297 308 description={data.conversation.description} 298 309 /> 299 - {statement ? ( 300 - <View style={styles.statementCard}> 301 - <Text style={[a.text_md, a.font_bold, {lineHeight: 22}]}> 302 - {statement.txt} 303 - </Text> 304 - </View> 305 - ) : null} 306 310 <Pressable 307 311 style={styles.signInButton} 308 312 onPress={openAssembly}