this repo has no description
10
fork

Configure Feed

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

feat: add Share button to manage profile page when project is live

Reuses explore project-page share copy and the canonical /explore/{handle}
URL. Hidden until a published registry handle exists (not takedown).

Made-with: Cursor

+32
+32
routes/explore/manage.tsx
··· 11 11 import { getEffectiveAccountType } from "../../lib/account-types.ts"; 12 12 import { listProfileUpdates } from "../../lib/profile-updates.ts"; 13 13 import { bskyCdnAvatarUrl } from "../../lib/avatar.ts"; 14 + import ShareButton from "../../islands/ShareButton.tsx"; 14 15 15 16 export const handler = define.handlers({ 16 17 async GET(ctx) { ··· 139 140 : null; 140 141 141 142 const publicProfileHandle = takedown ? null : existing?.handle ?? null; 143 + const shareUrl = publicProfileHandle 144 + ? new URL( 145 + `/explore/${encodeURIComponent(publicProfileHandle)}`, 146 + ctx.url.origin, 147 + ).href 148 + : null; 149 + const shareTitleName = (existing?.name?.trim() || 150 + initial?.name?.trim() || 151 + publicProfileHandle || 152 + user.handle).trim(); 142 153 const updates = existing 143 154 ? await listProfileUpdates(user.did, { limit: 8 }).catch(() => []) 144 155 : []; ··· 150 161 initialAvatarUrl={initialAvatarUrl} 151 162 initialPublished={!!existing && !takedown} 152 163 publicProfileHandle={publicProfileHandle} 164 + shareUrl={shareUrl} 165 + shareTitleName={shareTitleName} 153 166 updates={updates.map((update) => ({ 154 167 rkey: update.rkey, 155 168 title: update.title, ··· 172 185 initialAvatarUrl: string | null; 173 186 initialPublished: boolean; 174 187 publicProfileHandle: string | null; 188 + /** Absolute project page URL when published; null if no live listing yet. */ 189 + shareUrl: string | null; 190 + /** Display name for native share / clipboard context. */ 191 + shareTitleName: string; 175 192 updates: Parameters<typeof ProfileUpdateEditor>[0]["initialUpdates"]; 176 193 takedown: { reason: string; at: number | null } | null; 177 194 // deno-lint-ignore no-explicit-any ··· 186 203 initialAvatarUrl, 187 204 initialPublished, 188 205 publicProfileHandle, 206 + shareUrl, 207 + shareTitleName, 189 208 updates, 190 209 takedown, 191 210 t, 192 211 }: ManagePageProps, 193 212 ) { 194 213 const explore = t.explore; 214 + const shareCopy = explore.detail.share; 195 215 const takedownCopy = t.manageTakedown; 196 216 return ( 197 217 <div id="page-top"> ··· 204 224 <h1 class="text-section">{explore.manage.headline}</h1> 205 225 <p class="text-body mt-2">{explore.manage.subhead}</p> 206 226 </div> 227 + {shareUrl && ( 228 + <ShareButton 229 + url={shareUrl} 230 + title={shareCopy.shareTitle(shareTitleName)} 231 + copy={{ 232 + button: shareCopy.button, 233 + copyLink: shareCopy.copyLink, 234 + copied: shareCopy.copied, 235 + copyFailed: shareCopy.copyFailed, 236 + }} 237 + /> 238 + )} 207 239 </div> 208 240 209 241 {takedown && (