Skip to content

feat: enhance publishing with title-based naming and shared storage #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 52 additions & 78 deletions src/pages/p2p/editor/dweb.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { update, showSpinner, basicCSS } from './codeEditor.js';
import { $, uploadButton, protocolSelect, fetchButton, fetchCidInput } from './common.js';

// assemble code before uploading
// Assemble code before uploading
export async function assembleCode() {
const title = document.getElementById("titleInput").value.trim();
if (!title) {
alert("Please enter a title for your project.");
return;
}

// Display loading spinner
showSpinner(true);

Expand All @@ -22,7 +28,8 @@ export async function assembleCode() {

// Convert the combined code into a Blob
const blob = new Blob([combinedCode], { type: 'text/html' });
const file = new File([blob], "index.html", { type: 'text/html' });
const fileName = `${title.replace(/\s+/g, '-').toLowerCase()}.html`;
const file = new File([blob], fileName, { type: 'text/html' });

// Upload the file
await uploadFile(file);
Expand All @@ -36,90 +43,61 @@ async function uploadFile(file) {
const protocol = protocolSelect.value;
console.log(`[uploadFile] Uploading ${file.name}, protocol: ${protocol}`);

let url;
if (protocol === 'hyper') {
const hyperdriveUrl = await generateHyperdriveKey();
const url = `${hyperdriveUrl}${encodeURIComponent(file.name)}`;
const cleanUrl = url.replace(/index\.html$/, '');
const hyperdriveUrl = await getOrCreateHyperdrive();
url = `${hyperdriveUrl}${encodeURIComponent(file.name)}`;
console.log(`[uploadFile] Hyper URL: ${url}`);

try {
const response = await fetch(url, {
method: 'PUT',
body: file, // Send raw file bytes
headers: {
'Content-Type': file.type || 'text/html'
}
});

console.log(`[uploadFile] Response status: ${response.status}, ok: ${response.ok}`);
if (!response.ok) {
const errorText = await response.text();
console.error(`[uploadFile] Error uploading ${file.name}: ${errorText}`);
addError(file.name, errorText);
return;
}

addURL(cleanUrl);
} catch (error) {
console.error(`[uploadFile] Error uploading ${file.name}:`, error);
addError(file.name, error.message);
} finally {
showSpinner(false);
}
} else {
// IPFS upload with FormData
const formData = new FormData();
console.log(`[uploadFile] Appending file for IPFS: ${file.name}`);
formData.append('file', file, file.name);

const url = `ipfs://bafyaabakaieac/`;
url = `ipfs://bafyaabakaieac/${encodeURIComponent(file.name)}`;
console.log(`[uploadFile] IPFS URL: ${url}`);
}

try {
const response = await fetch(url, {
method: 'PUT',
body: formData,
});

console.log(`[uploadFile] IPFS Response status: ${response.status}, ok: ${response.ok}`);
if (!response.ok) {
const errorText = await response.text();
console.error(`[uploadFile] IPFS Error: ${errorText}`);
addError(file.name, errorText);
return;
try {
const response = await fetch(url, {
method: 'PUT',
body: file, // Send raw file bytes
headers: {
'Content-Type': file.type || 'text/html'
}
});

const locationHeader = response.headers.get('Location');
console.log(`[uploadFile] IPFS Location header: ${locationHeader}`);
addURL(locationHeader);
} catch (error) {
console.error(`[uploadFile] Error uploading to IPFS:`, error);
addError(file.name, error.message);
} finally {
showSpinner(false);
console.log(`[uploadFile] Response status: ${response.status}, ok: ${response.ok}`);
if (!response.ok) {
const errorText = await response.text();
console.error(`[uploadFile] Error uploading ${file.name}: ${errorText}`);
addError(file.name, errorText);
return;
}

const finalUrl = protocol === 'hyper' ? url : response.headers.get('Location');
addURL(finalUrl);
} catch (error) {
console.error(`[uploadFile] Error uploading ${file.name}:`, error);
addError(file.name, error.message);
} finally {
showSpinner(false);
}
}

async function generateHyperdriveKey() {
// Generate a unique name using timestamp and random string
const timestamp = Date.now();
const randomStr = Math.random().toString(36).substring(2, 8);
const uniqueName = `p2p-editor-${timestamp}-${randomStr}`;
console.log(`[generateHyperdriveKey] Generating key for name: ${uniqueName}`);
let hyperdriveUrl = null;

try {
const response = await fetch(`hyper://localhost/?key=${encodeURIComponent(uniqueName)}`, { method: 'POST' });
if (!response.ok) {
throw new Error(`Failed to generate Hyperdrive key: ${response.statusText}`);
async function getOrCreateHyperdrive() {
if (!hyperdriveUrl) {
const name = 'p2p-editor';
try {
const response = await fetch(`hyper://localhost/?key=${encodeURIComponent(name)}`, { method: 'POST' });
if (!response.ok) {
throw new Error(`Failed to generate Hyperdrive key: ${response.statusText}`);
}
hyperdriveUrl = await response.text();
console.log(`[getOrCreateHyperdrive] Hyperdrive URL: ${hyperdriveUrl}`);
} catch (error) {
console.error('[getOrCreateHyperdrive] Error generating Hyperdrive key:', error);
throw error;
}
const hyperUrl = await response.text();
console.log(`[generateHyperdriveKey] Hyperdrive URL: ${hyperUrl}`);
return hyperUrl; // Returns the hyper:// URL
} catch (error) {
console.error('[generateHyperdriveKey] Error generating Hyperdrive key:', error);
throw error;
}
return hyperdriveUrl;
}

function addURL(url) {
Expand Down Expand Up @@ -191,11 +169,7 @@ function parseAndDisplayData(data) {

// Extracting CSS
const styleElements = Array.from(doc.querySelectorAll('style'));

// Remove the first element (agregore theme CSS)
styleElements.shift();

// Now combine the CSS from the remaining <style> elements
styleElements.shift(); // Remove the first element (basicCSS)
let cssContent = styleElements.map(style => style.innerHTML).join('');

// Extracting JavaScript
Expand All @@ -213,4 +187,4 @@ function parseAndDisplayData(data) {
$('#cssCode').value = cssContent;
$('#javascriptCode').value = jsContent;
update(0);
}
}
14 changes: 7 additions & 7 deletions src/pages/p2p/editor/index.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<meta lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Builder</title>
<title>P2P Editor</title>
<link rel="stylesheet" type="text/css" href="styles.css">

<main>
Expand All @@ -27,20 +27,20 @@
<div id="dweb-container">
<div>
<label for="protocolSelect">
Protocol:
<select id="protocolSelect">
<option value="ipfs" selected>Inter-Planetary File System (IPFS://)</option>
<option value="hyper">Hypercore-Protocol (HYPER://)</option>
<option value="ipfs" selected>IPFS://</option>
<option value="hyper">HYPER://</option>
</select>
</label>
<input type="text" id="titleInput" placeholder="Project title" required>
<button id="uploadButton">Upload to DWeb</button>

</div>
<div id="fetchContainer">
<input id="fetchCidInput" type="text" placeholder="Enter IPFS CID or Hyperdrive URL ">
<input id="fetchCidInput" type="text" placeholder="Enter IPFS CID or Hyper URL ">
<button id="fetchButton">Fetch from DWeb</button>
</div>

</div>
<ul id="uploadListBox"></ul>
</main>
Expand Down