Skip to content

Commit

Permalink
deploy: e4e6b81
Browse files Browse the repository at this point in the history
  • Loading branch information
miladsoft committed Jan 7, 2025
1 parent 56da951 commit 733b4ee
Show file tree
Hide file tree
Showing 18 changed files with 548 additions and 23 deletions.
4 changes: 2 additions & 2 deletions 404.html

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions _astro/AngorPosts.xPW8KPv2.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions _astro/Hero.B20rh2FH.js → _astro/Hero.DUUb4NEp.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions _astro/_commonjsHelpers.CqkleIqs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
function e(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}export{e as g};
9 changes: 0 additions & 9 deletions _astro/index.CZHH1fVn.css

This file was deleted.

9 changes: 9 additions & 0 deletions _astro/index.EYjod9Of.css

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions angor-posts/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions blog/article/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions btc-price/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions how-angor-works/index.html

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions index.html

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions nostr/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"liveServer.settings.port": 5502
}
17 changes: 17 additions & 0 deletions nostr/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Angor Posts on Nostr</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>

<div class="container">
<h2>Angor Posts on Nostr</h2>
<div id="post_results" class="post-results"></div>
</div>

<script src="scripts.js"></script>
</body>
</html>
5 changes: 5 additions & 0 deletions nostr/keys.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
{
"nostrPubKey": "3ab7c2108524b7d1c1c585f09c1b7e194f5e7f225a5bb947f378e074d74e9dbf"
}
]
9 changes: 9 additions & 0 deletions nostr/relays.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"relays": [
"wss://eden.nostr.land",
"wss://nostr.wine",
"wss://relay.damus.io",
"wss://relay.nostr.band",
"wss://relay.snort.social"
]
}
204 changes: 204 additions & 0 deletions nostr/scripts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
document.addEventListener('DOMContentLoaded', () => {
loadkeys();
loadRelays();
window.addEventListener('scroll', handleScroll);
});

let keys = [];
let relayUrls = [];
let metadataFetched = {};

function loadkeys() {
fetch('keys.json')
.then(response => response.json())
.then(data => {
keys = data;
fetchAllPosts();
})
.catch(error => console.error('Error loading keys:', error));
}

function loadRelays() {
fetch('relays.json')
.then(response => response.json())
.then(data => {
relayUrls = data.relays;
fetchAllPosts();
})
.catch(error => console.error('Error loading relays:', error));
}

function fetchAllPosts() {
keys.forEach(project => {
fetchPosts(project.nostrPubKey, Date.now() / 1000);
});
}

function fetchPosts(pubkey, until) {
relayUrls.forEach(relayUrl => {
const socket = new WebSocket(relayUrl);

socket.addEventListener('open', () => {
// Send metadata request first
const metadataFilter = {
"kinds": [0],
"authors": [pubkey]
};
socket.send(JSON.stringify([
"REQ",
`metadata-${pubkey}`,
metadataFilter
]));

// Then send posts request
const postFilter = {
"kinds": [1],
"authors": [pubkey],
"until": until,
"limit": 10
};
socket.send(JSON.stringify([
"REQ",
`posts-${pubkey}`,
postFilter
]));
});

socket.addEventListener('message', async event => {
try {
const [type, subId, eventData] = JSON.parse(event.data);
if (type === 'EVENT') {
if (eventData.kind === 0) {
// Handle metadata event
const metadata = JSON.parse(eventData.content);
const project = keys.find(p => p.nostrPubKey === eventData.pubkey);
if (project) {
project.metadata = {
name: metadata.name || '',
picture: metadata.picture || 'default-avatar.png',
about: metadata.about || '',
nip05: metadata.nip05 || ''
};
updateExistingPosts(eventData.pubkey, project.metadata);
}
} else if (eventData.kind === 1) {
// Handle post event
displayPost(eventData);
}
}
} catch (error) {
console.error('Error processing event:', error);
}
});

socket.addEventListener('error', error => {
console.error('WebSocket error:', error);
});

socket.addEventListener('close', () => {
console.log("Disconnected from relay:", relayUrl);
});
});
}

function handleMetadataEvent(pubkey, content) {
try {
const metadata = JSON.parse(content);
const project = keys.find(project => project.nostrPubKey === pubkey);
if (project) {
// Parse picture URL from metadata
let picture = metadata.picture || '';
// Handle base64 images
if (picture.startsWith('data:image')) {
picture = picture;
} else if (!picture.startsWith('http')) {
picture = 'default-avatar.png';
}
project.metadata = {
...metadata,
picture: picture
};
// Update existing posts with new metadata
updateExistingPosts(pubkey, project.metadata);
}
} catch (error) {
console.error('Error parsing metadata:', error);
}
}

function updateExistingPosts(pubkey, metadata) {
const posts = document.querySelectorAll('.post-card');
posts.forEach(post => {
const authorPubkey = post.querySelector('.author').dataset.pubkey;
if (authorPubkey === pubkey) {
const profileImg = post.querySelector('.post-header img');
const authorName = post.querySelector('.author');
if (profileImg) profileImg.src = metadata.picture || 'default-avatar.png';
if (authorName) authorName.textContent = metadata.name || prettyFormatKey(pubkey);
}
});
}

function displayPost(post) {
const postContainer = document.getElementById('post_results');
const project = keys.find(p => p.nostrPubKey === post.pubkey);
const metadata = project && project.metadata ? project.metadata : {};

const postDiv = document.createElement('div');
postDiv.classList.add('post-card');
postDiv.dataset.pubkey = post.pubkey;
postDiv.innerHTML = `
<div class="post-header">
<img src="${metadata.picture || 'default-avatar.png'}"
alt="Profile Picture"
onerror="this.src='default-avatar.png'"
class="profile-image"
>
<div class="author-info">
<div class="author" data-pubkey="${post.pubkey}">
${metadata.name || prettyFormatKey(post.pubkey)}
</div>
${metadata.nip05 ? `<div class="nip05">${metadata.nip05}</div>` : ''}
</div>
</div>
<div class="post-content">${parseContent(post.content)}</div>
<div class="post-footer">Created At: ${dateToString(post.created_at)}</div>
`;
postContainer.appendChild(postDiv);
}

function parseContent(content) {
const urlRegex = /(https?:\/\/[^\s]+)/g;
return content.replace(urlRegex, url => {
if (url.match(/\.(jpeg|jpg|gif|png)$/) != null) {
return `<img src="${url}" alt="Image" style="max-width: 100%; height: auto;">`;
} else if (url.match(/\.(mp4|webm|ogg)$/) != null) {
return `<video controls style="max-width: 100%; height: auto;">
<source src="${url}" type="video/mp4">
Your browser does not support the video tag.
</video>`;
} else {
return `<a href="${url}" target="_blank">${url}</a>`;
}
});
}

function handleScroll() {
if (window.innerHeight + window.scrollY >= document.body.offsetHeight) {
const lastPost = document.querySelector('.post-card:last-child');
if (lastPost) {
const lastTimestamp = new Date(lastPost.querySelector('.post-footer').textContent.split('Created At: ')[1]).getTime() / 1000;
keys.forEach(project => {
fetchPosts(project.nostrPubKey, lastTimestamp);
});
}
}
}

function dateToString(unixTimestamp) {
return new Date(unixTimestamp * 1000).toLocaleString();
}

function prettyFormatKey(key) {
return key.slice(0, 4) + "..." + key.slice(-4);
}
Loading

0 comments on commit 733b4ee

Please sign in to comment.