Services Monitor
This commit is contained in:
65
.gitignore
vendored
65
.gitignore
vendored
@@ -1,63 +1,6 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 1.mp4
|
BTCforPlebs Website Videos/*
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 1.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 2.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 2.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 3.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 3.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 4.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 4.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 5.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 5.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 6.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 6.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin Basics & Why The Local Church Should Care.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin Basics & Why The Local Church Should Care.txt
|
|
||||||
BTCforPlebs Website Videos/Home/Home.mp4
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/1.0_where_to_start (1080p).html
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/1.0_where_to_start (1080p).mp4
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/1.0_where_to_start (1080p).txt
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/2.0_bitcoin_exchanges (1080p).html
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/2.0_bitcoin_exchanges (1080p).mp4
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/2.0_bitcoin_exchanges (1080p).txt
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/3.0_ownership (1080p).html
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/3.0_ownership (1080p).mp4
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/3.0_ownership (1080p).txt
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/4.0 Price.txt
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/4.0_Price.html
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/btcforplebs_opening_video (1080p).html
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/btcforplebs_opening_video (1080p).mp4
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/btcforplebs_opening_video (1080p).txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 1 .mp4
|
|
||||||
.gitignore
|
.gitignore
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 3 .mp4
|
node_modules/*
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 1.mp4
|
package-lock.json
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 1.txt
|
public/assets/data/link-status.json
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 2.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 2.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 3.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 3.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 4.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 4.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 5.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & the Bible Small Group Week 5.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 6.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin & The Bible Small Group Week 6.txt
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin Basics & Why The Local Church Should Care.mp4
|
|
||||||
BTCforPlebs Website Videos/Bitcoin-and-the-Bible/Bitcoin Basics & Why The Local Church Should Care.txt
|
|
||||||
BTCforPlebs Website Videos/Home/Home.mp4
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/1.0_where_to_start (1080p).html
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/1.0_where_to_start (1080p).mp4
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/1.0_where_to_start (1080p).txt
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/2.0_bitcoin_exchanges (1080p).html
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/2.0_bitcoin_exchanges (1080p).mp4
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/2.0_bitcoin_exchanges (1080p).txt
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/3.0_ownership (1080p).html
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/3.0_ownership (1080p).mp4
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/3.0_ownership (1080p).txt
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/4.0 Price.txt
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/4.0_Price.html
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/btcforplebs_opening_video (1080p).html
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/btcforplebs_opening_video (1080p).mp4
|
|
||||||
BTCforPlebs Website Videos/Learn-Bitcoin/btcforplebs_opening_video (1080p).txt
|
|
||||||
.DS_Store
|
|
||||||
|
|||||||
35
README.md
Normal file
35
README.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# BTCforPlebs.com Link Status Server
|
||||||
|
|
||||||
|
This server checks the status of various BTCforPlebs services and provides a JSON API endpoint.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. Install dependencies:
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Start the server:
|
||||||
|
```bash
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
The server will start on port 5252 by default. You can change this by setting the PORT environment variable.
|
||||||
|
|
||||||
|
## API Endpoints
|
||||||
|
|
||||||
|
- GET `/api/link-status` - Returns the status of all monitored services
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Edit `config.js` to modify:
|
||||||
|
- Port number
|
||||||
|
- Allowed CORS origins
|
||||||
|
- Add or remove monitored URLs
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
The server uses:
|
||||||
|
- Express.js for the API server
|
||||||
|
- node-fetch for making HTTP requests
|
||||||
|
- CORS enabled for specified origins
|
||||||
93
checklinks.js
Normal file
93
checklinks.js
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
const express = require("express");
|
||||||
|
const fetch = require("node-fetch");
|
||||||
|
const https = require("https");
|
||||||
|
const config = require('./config');
|
||||||
|
const app = express();
|
||||||
|
|
||||||
|
const links = [
|
||||||
|
"https://relay.btcforplebs.com",
|
||||||
|
"https://live.btcforplebs.com",
|
||||||
|
"https://bloom.btcforplebs.com",
|
||||||
|
"https://mempool.btcforplebs.com",
|
||||||
|
"https://lightning.btcforplebs.com",
|
||||||
|
"https://nostrudel.btcforplebs.com",
|
||||||
|
"https://nosotros.btcforplebs.com",
|
||||||
|
"https://mint.btcforplebs.com",
|
||||||
|
"https://cashu.btcforplebs.com",
|
||||||
|
"https://nostrapps.com",
|
||||||
|
// Add more links as needed
|
||||||
|
];
|
||||||
|
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
console.log("Received request:", req.url);
|
||||||
|
const origin = req.headers.origin;
|
||||||
|
if (config.allowedOrigins.includes(origin)) {
|
||||||
|
res.header("Access-Control-Allow-Origin", origin);
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get("/api/link-status", async (req, res) => {
|
||||||
|
console.log("Checking link statuses..."); // Add this line
|
||||||
|
const results = {};
|
||||||
|
|
||||||
|
const agent = new https.Agent({
|
||||||
|
rejectUnauthorized: false // This helps with self-signed certificates
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const url of links) {
|
||||||
|
try {
|
||||||
|
console.log(`Checking ${url}...`);
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
|
||||||
|
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
|
||||||
|
},
|
||||||
|
timeout: 10000,
|
||||||
|
agent
|
||||||
|
});
|
||||||
|
console.log(`${url} status: ${response.status}`);
|
||||||
|
|
||||||
|
// If response is OK, it's online
|
||||||
|
if (response.ok) {
|
||||||
|
results[url] = "online";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Special check for mint.btcforplebs.com
|
||||||
|
if (url.includes("mint.btcforplebs.com")) {
|
||||||
|
try {
|
||||||
|
const text = await response.text();
|
||||||
|
console.log(`Mint response text:`, text);
|
||||||
|
const json = JSON.parse(text);
|
||||||
|
console.log(`Mint parsed JSON:`, json);
|
||||||
|
console.log(`Content-Type:`, response.headers.get('content-type'));
|
||||||
|
if (json.detail === "Not Found") {
|
||||||
|
console.log(`Mint matched expected response, marking as online`);
|
||||||
|
results[url] = "online";
|
||||||
|
} else {
|
||||||
|
console.log(`Mint response didn't match expected format`);
|
||||||
|
results[url] = "offline";
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error processing mint response:`, error);
|
||||||
|
results[url] = "offline";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// For all other URLs, if not OK then offline
|
||||||
|
results[url] = "offline";
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Error checking ${url}:`, error.message);
|
||||||
|
results[url] = "offline";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Final results:", results);
|
||||||
|
res.json(results);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(config.port, () => {
|
||||||
|
console.log(`Link status API running on port ${config.port}`);
|
||||||
|
});
|
||||||
9
config.js
Normal file
9
config.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
module.exports = {
|
||||||
|
port: process.env.PORT || 5252,
|
||||||
|
// Add any other configuration variables here
|
||||||
|
allowedOrigins: [
|
||||||
|
'http://localhost:5252',
|
||||||
|
'https://btcforplebs.com',
|
||||||
|
'https://www.btcforplebs.com'
|
||||||
|
]
|
||||||
|
};
|
||||||
26
package.json
Normal file
26
package.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "btcforplebs.com",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node checklinks.js",
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/btcforplebs/BTCforPlebs.com.git"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"type": "commonjs",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/btcforplebs/BTCforPlebs.com/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/btcforplebs/BTCforPlebs.com#readme",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^5.1.0",
|
||||||
|
"node-fetch": "^2.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
92
public/assets/js/home.js
Normal file
92
public/assets/js/home.js
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
// Store statuses globally
|
||||||
|
let linkStatuses = {};
|
||||||
|
|
||||||
|
// Fetch statuses on page load
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
// Fetch statuses immediately but keep folders closed
|
||||||
|
fetch("http://localhost:5252/api/link-status")
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(statuses => {
|
||||||
|
linkStatuses = statuses; // Store for later use
|
||||||
|
console.log("Cached link statuses:", linkStatuses);
|
||||||
|
})
|
||||||
|
.catch(error => console.error("Error:", error));
|
||||||
|
});
|
||||||
|
|
||||||
|
// Helper function to update status emojis
|
||||||
|
function updateFolderStatuses(folder, statuses) {
|
||||||
|
folder.querySelectorAll("a").forEach(link => {
|
||||||
|
const url = link.href;
|
||||||
|
const matchingUrl = Object.keys(statuses).find(statusUrl =>
|
||||||
|
url.includes(new URL(statusUrl).hostname)
|
||||||
|
);
|
||||||
|
const status = matchingUrl ? statuses[matchingUrl] : "unknown";
|
||||||
|
const emoji = status === "online" ? "🟢" : "🔴";
|
||||||
|
|
||||||
|
const statusSpan = link.querySelector('.status-emoji');
|
||||||
|
if (statusSpan) {
|
||||||
|
statusSpan.textContent = emoji;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleFolder(folderId, buttonId) {
|
||||||
|
const folder = document.getElementById(folderId);
|
||||||
|
const button = document.getElementById(buttonId);
|
||||||
|
if (!folder || !button) return;
|
||||||
|
|
||||||
|
if (folder.style.display === "none" || folder.style.display === "") {
|
||||||
|
folder.style.display = "block";
|
||||||
|
button.innerHTML = button.innerHTML.replace("↓", "↑");
|
||||||
|
|
||||||
|
// Use cached statuses if available, otherwise fetch new ones
|
||||||
|
if (Object.keys(linkStatuses).length > 0) {
|
||||||
|
updateFolderStatuses(folder, linkStatuses);
|
||||||
|
} else {
|
||||||
|
fetch("http://localhost:5252/api/link-status")
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(statuses => {
|
||||||
|
linkStatuses = statuses;
|
||||||
|
updateFolderStatuses(folder, statuses);
|
||||||
|
})
|
||||||
|
.catch(error => console.error("Error:", error));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
folder.style.display = "none";
|
||||||
|
button.innerHTML = button.innerHTML.replace("↑", "↓");
|
||||||
|
}
|
||||||
|
// Wait for both DOM and fetch to complete
|
||||||
|
async function init() {
|
||||||
|
try {
|
||||||
|
// Fetch the status first
|
||||||
|
console.log("Fetching statuses...");
|
||||||
|
const response = await fetch("http://localhost:5252/api/link-status");
|
||||||
|
const statuses = await response.json();
|
||||||
|
console.log("Got statuses:", statuses);
|
||||||
|
|
||||||
|
// Now update the links
|
||||||
|
document.querySelectorAll(".links a").forEach(link => {
|
||||||
|
const url = link.href;
|
||||||
|
console.log('Checking link:', url); // Debug log
|
||||||
|
const matchingUrl = Object.keys(statuses).find(statusUrl => {
|
||||||
|
const linkHostname = new URL(url).hostname;
|
||||||
|
const statusHostname = new URL(statusUrl).hostname;
|
||||||
|
console.log('Comparing:', linkHostname, 'with', statusHostname); // Debug log
|
||||||
|
return linkHostname === statusHostname;
|
||||||
|
});
|
||||||
|
console.log('Matching URL found:', matchingUrl); // Debug log
|
||||||
|
const status = matchingUrl ? statuses[matchingUrl] : "unknown";
|
||||||
|
console.log('Status for', url, 'is', status); // Debug log
|
||||||
|
const emoji = status === "online" ? "🟢" : "🔴";
|
||||||
|
|
||||||
|
// Find the span inside this link and update it
|
||||||
|
const statusSpan = link.querySelector('.status-emoji');
|
||||||
|
if (statusSpan) {
|
||||||
|
statusSpan.textContent = emoji;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,32 +26,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function navigateToSection(select) {
|
|
||||||
const sectionId = select.value;
|
|
||||||
if (sectionId) {
|
|
||||||
document.getElementById(sectionId).scrollIntoView({ behavior: 'smooth' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to prefetch a URL
|
|
||||||
function prefetch(url) {
|
|
||||||
const link = document.createElement('link');
|
|
||||||
link.rel = 'prefetch';
|
|
||||||
link.href = url;
|
|
||||||
document.head.appendChild(link);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add event listeners to your links
|
// Footer Loader and Event Listeners
|
||||||
const links = document.querySelectorAll('a.prefetch');
|
|
||||||
|
|
||||||
links.forEach(link => {
|
|
||||||
link.addEventListener('mouseenter', () => {
|
|
||||||
const url = link.href; // Get the link URL
|
|
||||||
prefetch(url); // Call prefetch function
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Footer Loader and Event Listeners
|
|
||||||
fetch('/parts/footer.html')
|
fetch('/parts/footer.html')
|
||||||
.then(response => response.text())
|
.then(response => response.text())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
|
|||||||
@@ -17,8 +17,8 @@
|
|||||||
<link rel="icon" href="/images/favicon.png" type="image/png">
|
<link rel="icon" href="/images/favicon.png" type="image/png">
|
||||||
|
|
||||||
<!-- scripts -->
|
<!-- scripts -->
|
||||||
<script src="/assets/js/scripts.js" defer></script>
|
|
||||||
|
|
||||||
|
<script src="/assets/js/home.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/css/main.css">
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" rel="stylesheet">
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
@@ -40,32 +40,35 @@
|
|||||||
</div>
|
</div>
|
||||||
<button class="button" id="bitcoin-folder-btn" onclick="toggleFolder('folder2', 'bitcoin-folder-btn')">Use Bitcoin <span style="color: #F7931A;">↓</span></button>
|
<button class="button" id="bitcoin-folder-btn" onclick="toggleFolder('folder2', 'bitcoin-folder-btn')">Use Bitcoin <span style="color: #F7931A;">↓</span></button>
|
||||||
<div class="links" id="folder2">
|
<div class="links" id="folder2">
|
||||||
All apps hosted by BTCforPlebs<br></br>
|
<a href="https://lightning.btcforplebs.com" target="_blank" class="prefetch">Lightning <span class="status-emoji"></span></a>
|
||||||
<a href="https://lightning.btcforplebs.com" target="_blank" class="prefetch">Lightning</a>
|
<a href="https://mempool.btcforplebs.com" target="_blank" class="prefetch">Mempool <span class="status-emoji"></span></a>
|
||||||
<a href="https://mempool.btcforplebs.com" target="_blank" class="prefetch">Mempool</a>
|
<a href="https://bitview.space/" target="_blank" class="prefetch">Bitview.space ⚪️</span></a>
|
||||||
<a href="https://bitview.space/" target="_blank" class="prefetch">Bitview.space (external host)</a>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="button" id="nostr-folder-btn" onclick="toggleFolder('folder1', 'nostr-folder-btn')">Use Nostr <span style="color: #F7931A;">↓</span></button>
|
<button class="button" id="nostr-folder-btn" onclick="toggleFolder('folder1', 'nostr-folder-btn')">Use Nostr <span style="color: #F7931A;">↓</span></button>
|
||||||
<div class="links" id="folder1">
|
<div class="links" id="folder1">
|
||||||
All apps hosted by BTCforPlebs<br></br>
|
<a href="https://nostrudel.btcforplebs.com" target="_blank" class="prefetch">Nostrudel <span class="status-emoji"></span></a>
|
||||||
<a href="https://nostrudel.btcforplebs.com" target="_blank" class="prefetch">Nostrudel</a>
|
<a href="https://nosotros.btcforplebs.com" target="_blank" class="prefetch">Nosotros <span class="status-emoji"></span></a>
|
||||||
<a href="https://nosotros.btcforplebs.com" target="_blank" class="prefetch">Nosotros</a>
|
<a href="https://bloom.btcforplebs.com" target="_blank" class="prefetch">Bloom <span class="status-emoji"></span></a>
|
||||||
<a href="https://bloom.btcforplebs.com" target="_blank" class="prefetch">Bloom</a>
|
<a href="https://relay.btcforplebs.com" target="_blank" class="prefetch">Relay <span class="status-emoji"></span></a>
|
||||||
<a href="https://btcforplebs.com/relay" target="_blank" class="prefetch">Relay</a>
|
<a href="https://nostrapps.com" target="_blank">NostrApps.com ⚪️</a>
|
||||||
<br></br>
|
|
||||||
<a href="https://nostrapps.com" target="_blank">NostrApps.com</a>
|
|
||||||
</div>
|
</div>
|
||||||
<button class="button" id="cashu-folder-btn" onclick="toggleFolder('folder3', 'cashu-folder-btn')">Use Cashu <span style="color: #F7931A;">↓</span></button>
|
<button class="button" id="cashu-folder-btn" onclick="toggleFolder('folder3', 'cashu-folder-btn')">Use Cashu <span style="color: #F7931A;">↓</span></button>
|
||||||
<div class="links" id="folder3">
|
<div class="links" id="folder3">
|
||||||
<a href="https://cashu.me" class="prefetch">Cashu.me</a>
|
<a href="https://cashu.btcforplebs.com" class="prefetch">Cashu Web App <span class="status-emoji"></span></a>
|
||||||
|
<a href="https://macadamia.cash" class="prefetch">Macadamia (iOS) ⚪️</a>
|
||||||
|
<a href="https://minibits.cash" class="prefetch">Minibits (Android) ⚪️</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="https://live.btcforplebs.com" class="button" class="prefetch">BTCforPlebs Live</a>
|
<a href="https://live.btcforplebs.com" class="button" class="prefetch">BTCforPlebs Live<span class="status-emoji"></span></a>
|
||||||
<br></br>
|
<br></br>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="footer"></div>
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div id="footer"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<title>Learn Bitcoin</title>
|
<title>Learn Bitcoin</title>
|
||||||
|
|
||||||
<!-- scripts -->
|
<!-- scripts -->
|
||||||
<script src="/assets/js/scripts.js" defer></script>
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<link rel="stylesheet" href="/assets/css/main.css">
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
@@ -194,7 +193,12 @@
|
|||||||
|
|
||||||
<div id="back-to-top">
|
<div id="back-to-top">
|
||||||
<a href="#top" title="Back to Top">🔝</a>
|
<a href="#top" title="Back to Top">🔝</a>
|
||||||
|
<script>function navigateToSection(select) {
|
||||||
|
const sectionId = select.value;
|
||||||
|
if (sectionId) {
|
||||||
|
document.getElementById(sectionId).scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
}</script>
|
||||||
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -9,7 +9,6 @@
|
|||||||
<link rel="stylesheet" href="/assets/css/main.css">
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
<link rel="apple-touch-icon" href="/images/apple-touch-icon.png">
|
<link rel="apple-touch-icon" href="/images/apple-touch-icon.png">
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" rel="stylesheet">
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.6.0/css/all.min.css" rel="stylesheet">
|
||||||
<script src="/assets/js/scripts.js" defer></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- Bitcoin Price Banner -->
|
<!-- Bitcoin Price Banner -->
|
||||||
@@ -107,5 +106,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="footer"></div>
|
<div id="footer"></div>
|
||||||
<a href="#top" title="Back to Top">🔝</a>
|
<a href="#top" title="Back to Top">🔝</a>
|
||||||
</body>
|
<script>function navigateToSection(select) {
|
||||||
|
const sectionId = select.value;
|
||||||
|
if (sectionId) {
|
||||||
|
document.getElementById(sectionId).scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
}</script>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -48,7 +48,12 @@
|
|||||||
<div id="footer"></div>
|
<div id="footer"></div>
|
||||||
|
|
||||||
<a href="#top" title="Back to Top">🔝</a>
|
<a href="#top" title="Back to Top">🔝</a>
|
||||||
|
<script>function navigateToSection(select) {
|
||||||
|
const sectionId = select.value;
|
||||||
|
if (sectionId) {
|
||||||
|
document.getElementById(sectionId).scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
}</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<link rel="stylesheet" href="/assets/css/main.css">
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
<footer>
|
<footer>
|
||||||
<script src="/assets/js/scripts.js" defer></script>
|
<script src="/assets/js/scripts.js"></script>
|
||||||
<h3>We operate on solely on Bitcoin donations; from a pleb just like you!</h3>
|
<h3>We operate on solely on Bitcoin donations; from a pleb just like you!</h3>
|
||||||
|
|
||||||
<!-- Button Section -->
|
<!-- Button Section -->
|
||||||
|
|||||||
Reference in New Issue
Block a user