Skip to content

Commit

Permalink
First attempt at rendering external identities
Browse files Browse the repository at this point in the history
  • Loading branch information
sondreb committed Dec 22, 2024
1 parent e4742c9 commit d1c9bd6
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 1 deletion.
118 changes: 117 additions & 1 deletion src/app/pages/project/project.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { CommonModule, DatePipe } from '@angular/common';
import { BreadcrumbComponent } from '../../components/breadcrumb.component';
import { RelayService } from '../../services/relay.service';
import NDK, { NDKKind, NDKUser } from '@nostr-dev-kit/ndk';
import NDK, { NDKEvent, NDKKind, NDKUser } from '@nostr-dev-kit/ndk';
import { AgoPipe } from '../../pipes/ago.pipe';
import { ImagePopupComponent } from '../../components/image-popup.component';

Expand All @@ -18,6 +18,12 @@ export interface FaqItem {
answer: string;
}

interface ExternalIdentity {
platform: string;
username: string;
proofUrl?: string;
}

@Component({
selector: 'app-project',
standalone: true,
Expand Down Expand Up @@ -133,6 +139,21 @@ export interface FaqItem {
njump
</a>
}
<div class="social-links">
@for (identity of externalIdentities(); track identity.platform) {
<a
[href]="getSocialLink(identity)"
target="_blank"
class="social-link"
[title]="identity.username"
>
<span class="material-icons">{{
getSocialIcon(identity.platform)
}}</span>
<span>{{ formatUsername(identity.username) }}</span>
</a>
}
</div>
</div>
<div class="invest-button-container">
<button
Expand Down Expand Up @@ -908,6 +929,33 @@ export interface FaqItem {
padding: 1rem;
}
}
.social-links {
display: flex;
gap: 1rem;
margin-top: 0.5rem;
flex-wrap: wrap;
}
.social-link {
color: var(--text-secondary);
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.25rem 0.5rem;
border-radius: 4px;
transition: all 0.2s ease;
}
.social-link:hover {
background: var(--surface-hover);
color: var(--text-primary);
}
.social-link .material-icons {
font-size: 1.2rem;
}
`,
],
})
Expand Down Expand Up @@ -1100,6 +1148,11 @@ export class ProjectComponent implements OnInit, OnDestroy {
const profileSub = this.relay.profileUpdates.subscribe((update) => {
if (update.pubkey == projectData.details.nostrPubKey) {
projectData.metadata = update.profile;

// Parse the external identities from profile metadata.
this.externalIdentities.set(
this.getExternalIdentities(update.event)
);
}

// if (projectData?.details?.nostrPubKey === update.pubkey) {
Expand Down Expand Up @@ -1171,4 +1224,67 @@ export class ProjectComponent implements OnInit, OnDestroy {
if (invested === 0) return 0;
return Number(((penalties / invested) * 100).toFixed(1));
}

externalIdentities = signal<ExternalIdentity[]>([]);

getExternalIdentities(event: NDKEvent): ExternalIdentity[] {
console.log('Event:', event);

return event.tags
.filter((tag) => tag[0] === 'i')
.map((tag) => ({
platform: tag[1].split(':')[0],
username: tag[1].split(':')[1],
proofUrl: tag[2],
}));
}

getSocialIcon(platform: string): string {
const icons: { [key: string]: string } = {
github: 'code',
twitter: 'flutter_dash', // X icon
facebook: 'facebook',
telegram: 'telegram',
instagram: 'photo_camera',
linkedin: 'work',
youtube: 'smart_display',
mastodon: 'forum',
twitch: 'videogame_asset',
discord: 'chat',
email: 'email',
};

return icons[platform.toLowerCase()] || 'link';
}

getSocialLink(identity: ExternalIdentity): string {
const baseUrls: { [key: string]: string } = {
github: 'https://github.com/',
twitter: 'https://x.com/',
facebook: 'https://facebook.com/',
telegram: 'https://t.me/',
instagram: 'https://instagram.com/',
linkedin: 'https://linkedin.com/in/',
youtube: 'https://youtube.com/@',
mastodon: '', // Will use full username as it contains domain
twitch: 'https://twitch.tv/',
discord: 'https://discord.com/users/',
email: 'mailto:',
};

if (identity.platform === 'mastodon') {
return `https://${identity.username}`;
}

const baseUrl = baseUrls[identity.platform.toLowerCase()];
return baseUrl ? `${baseUrl}${identity.username}` : '#';
}

formatUsername(username: string): string {
// Remove domain parts for mastodon usernames
if (username.includes('@')) {
return '@' + username.split('@')[1];
}
return '@' + username;
}
}
3 changes: 3 additions & 0 deletions src/app/services/relay.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Subject } from 'rxjs';
export interface ProfileUpdate {
pubkey: string;
profile: NDKUserProfile;
event: NDKEvent
}

export interface ProjectUpdate {
Expand Down Expand Up @@ -165,9 +166,11 @@ export class RelayService {
sub.on('event', (event: NDKEvent) => {
try {
const profile = JSON.parse(event.content);

this.profileUpdates.next({
pubkey: event.pubkey,
profile,
event
});
} catch (error) {
console.error('Failed to parse profile:', error);
Expand Down
1 change: 1 addition & 0 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/png" href="favicon.png" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<app-root></app-root>
Expand Down

0 comments on commit d1c9bd6

Please sign in to comment.