atmo.rsvp
1
fork

Configure Feed

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

fix mentions, link to bsky/blacksky instead of atmo.rsvp profile for mentions and attendees

Florian d214be36 de6bb0b7

+41 -15
+1
src/lib/atproto/index.ts
··· 1 1 export { user, login, signup, logout } from './auth.svelte'; 2 + export { getProfileUrl } from './profile-url'; 2 3 3 4 export { 4 5 parseUri,
+7
src/lib/atproto/profile-url.ts
··· 1 + export function getProfileUrl(handleOrDid: string): string { 2 + const lower = handleOrDid.toLowerCase(); 3 + if (lower.endsWith('.blacksky.team') || lower.endsWith('.blacksky.app')) { 4 + return `https://blacksky.community/profile/${handleOrDid}`; 5 + } 6 + return `https://bsky.app/profile/${handleOrDid}`; 7 + }
+20 -10
src/lib/components/event-view/format.ts
··· 1 1 import { marked } from 'marked'; 2 2 import { sanitize } from '$lib/cal/sanitize'; 3 + import { getProfileUrl } from '$lib/atproto/profile-url'; 3 4 import type { FlatEventRecord } from '$lib/contrail'; 4 5 5 6 export function formatMonth(date: Date): string { ··· 111 112 let result = text; 112 113 113 114 if (facets && facets.length > 0) { 114 - const encoder = new TextEncoder(); 115 - const encoded = encoder.encode(text); 115 + const encoded = new TextEncoder().encode(text); 116 116 const decoder = new TextDecoder(); 117 117 118 - const sorted = [...facets].sort((a, b) => b.index.byteStart - a.index.byteStart); 118 + const sorted = [...facets].sort((a, b) => a.index.byteStart - b.index.byteStart); 119 + 120 + const parts: string[] = []; 121 + let cursor = 0; 119 122 120 123 for (const facet of sorted) { 121 124 const feature = facet.features?.[0]; 122 125 if (!feature) continue; 126 + if (facet.index.byteStart < cursor) continue; 123 127 124 - const segmentBytes = encoded.slice(facet.index.byteStart, facet.index.byteEnd); 125 - const segmentText = decoder.decode(segmentBytes); 128 + const segmentText = decoder.decode( 129 + encoded.slice(facet.index.byteStart, facet.index.byteEnd) 130 + ); 126 131 127 132 let mdLink: string | null = null; 128 133 switch (feature.$type) { 129 - case 'app.bsky.richtext.facet#mention': 130 - mdLink = `[${segmentText}](/${feature.did})`; 134 + case 'app.bsky.richtext.facet#mention': { 135 + const handle = segmentText.startsWith('@') ? segmentText.slice(1) : segmentText; 136 + mdLink = `[${segmentText}](${getProfileUrl(handle || feature.did || '')})`; 131 137 break; 138 + } 132 139 case 'app.bsky.richtext.facet#link': 133 140 mdLink = `[${segmentText}](${feature.uri})`; 134 141 break; ··· 138 145 } 139 146 140 147 if (mdLink) { 141 - const before = decoder.decode(encoded.slice(0, facet.index.byteStart)); 142 - const after = decoder.decode(encoded.slice(facet.index.byteEnd)); 143 - result = before + mdLink + after; 148 + parts.push(decoder.decode(encoded.slice(cursor, facet.index.byteStart))); 149 + parts.push(mdLink); 150 + cursor = facet.index.byteEnd; 144 151 } 145 152 } 153 + 154 + parts.push(decoder.decode(encoded.slice(cursor))); 155 + result = parts.join(''); 146 156 } 147 157 148 158 return marked.parse(result, { renderer }) as string;
+2 -5
src/lib/contrail.ts
··· 1 1 import '../lexicon-types/index.js'; 2 + import { getProfileUrl } from '$lib/atproto/profile-url'; 2 3 import type { EventData } from '$lib/event-types'; 3 4 import type { 4 5 RsvpAtmoGetProfile, ··· 159 160 }; 160 161 } 161 162 162 - function getProfileUrl(did: string, handle?: string) { 163 - return `/p/${handle || did}`; 164 - } 165 - 166 163 function buildAttendee( 167 164 did: string, 168 165 status: 'going' | 'interested', ··· 177 174 avatar: getProfileBlobUrl(did, profile?.record?.avatar), 178 175 name: profile?.record?.displayName || handle || did, 179 176 handle, 180 - url: getProfileUrl(did, handle) 177 + url: getProfileUrl(handle || did) 181 178 }; 182 179 } 183 180
+11
src/routes/(app)/+page.svelte
··· 42 42 {/each} 43 43 </div> 44 44 {/if} 45 + 46 + <footer class="text-base-500 dark:text-base-400 mt-24 text-center text-sm"> 47 + <a 48 + href="https://github.com/flo-bit/atmo-events" 49 + target="_blank" 50 + rel="noopener" 51 + class="hover:text-accent-600 dark:hover:text-accent-400 transition-colors" 52 + > 53 + View source on GitHub 54 + </a> 55 + </footer> 45 56 </div>