mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2025-09-09 07:28:44 +00:00
update
This commit is contained in:
94
src/components/video-modal.html
Normal file
94
src/components/video-modal.html
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<!-- components/video-modal.html -->
|
||||||
|
<div id="playerModal" class="hidden">
|
||||||
|
<!-- Navigation bar -->
|
||||||
|
<div
|
||||||
|
class="sticky top-0 z-60 bg-gray-900/95 backdrop-blur transition-transform duration-300"
|
||||||
|
id="modalNav"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="max-w-full w-full px-4 h-14 border-b border-gray-800 flex items-center"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
id="closeModal"
|
||||||
|
class="flex items-center gap-2 text-gray-400 hover:text-white transition-colors px-3 py-2 rounded-md hover:bg-gray-800/50"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="24"
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="w-5 h-5"
|
||||||
|
>
|
||||||
|
<path d="m12 19-7-7 7-7" />
|
||||||
|
<path d="M19 12H5" />
|
||||||
|
</svg>
|
||||||
|
<span class="font-medium">Back</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="video-container">
|
||||||
|
<video id="modalVideo" controls></video>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="video-info">
|
||||||
|
<!-- Video Title -->
|
||||||
|
<h2 id="videoTitle" class="text-2xl font-bold mb-2 text-white"></h2>
|
||||||
|
|
||||||
|
<!-- Video Timestamp -->
|
||||||
|
<div class="flex items-center justify-between text-sm text-gray-400 mb-4">
|
||||||
|
<span id="videoTimestamp">just now</span>
|
||||||
|
<div id="modalStatus" class="text-gray-300">
|
||||||
|
Initializing... Just give it a sec.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Creator info -->
|
||||||
|
<div class="flex items-center mb-4 p-4 bg-gray-800 rounded-lg">
|
||||||
|
<div class="w-12 h-12 rounded-full bg-gray-700 overflow-hidden">
|
||||||
|
<img
|
||||||
|
id="creatorAvatar"
|
||||||
|
src=""
|
||||||
|
alt="Creator"
|
||||||
|
class="w-full h-full object-cover"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="ml-4">
|
||||||
|
<h3 id="creatorName" class="font-medium text-lg text-white">
|
||||||
|
Creator Name
|
||||||
|
</h3>
|
||||||
|
<p id="creatorNpub" class="text-sm text-gray-400">npub...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Video Description -->
|
||||||
|
<div class="bg-gray-800 rounded-lg p-4 mb-4">
|
||||||
|
<p id="videoDescription" class="text-gray-300 whitespace-pre-wrap">
|
||||||
|
No description available.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Torrent stats -->
|
||||||
|
<div class="bg-gray-800 rounded-lg p-4">
|
||||||
|
<div class="w-full bg-gray-700 rounded-full h-2 mb-2">
|
||||||
|
<div
|
||||||
|
class="bg-blue-500 h-2 rounded-full"
|
||||||
|
id="modalProgress"
|
||||||
|
style="width: 0%"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-between text-sm text-gray-400">
|
||||||
|
<span id="modalPeers">Peers: 0</span>
|
||||||
|
<span id="modalSpeed">Speed: 0 KB/s</span>
|
||||||
|
<span id="modalDownloaded">Downloaded: 0 MB / 0 MB</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@@ -226,71 +226,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Improved Video Player Modal -->
|
<!-- Imported Video Player Modal -->
|
||||||
<div id="playerModal" class="hidden">
|
<div id="modalContainer"></div>
|
||||||
<div class="modal-content">
|
|
||||||
<div class="video-container">
|
|
||||||
<video id="modalVideo" controls></video>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="video-info">
|
|
||||||
<!-- Video Title -->
|
|
||||||
<h2 id="videoTitle" class="text-2xl font-bold mb-2 text-white"></h2>
|
|
||||||
|
|
||||||
<!-- Video Timestamp -->
|
|
||||||
<div
|
|
||||||
class="flex items-center justify-between text-sm text-gray-400 mb-4"
|
|
||||||
>
|
|
||||||
<span id="videoTimestamp">just now</span>
|
|
||||||
<div id="modalStatus" class="text-gray-300">
|
|
||||||
Initializing... Just give it a sec.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Creator info -->
|
|
||||||
<div class="flex items-center mb-4 p-4 bg-gray-800 rounded-lg">
|
|
||||||
<div
|
|
||||||
id="creatorAvatar"
|
|
||||||
class="w-12 h-12 rounded-full bg-gray-700 overflow-hidden"
|
|
||||||
>
|
|
||||||
<img src="" alt="Creator" class="w-full h-full object-cover" />
|
|
||||||
</div>
|
|
||||||
<div class="ml-4">
|
|
||||||
<h3 id="creatorName" class="font-medium text-lg text-white">
|
|
||||||
Creator Name
|
|
||||||
</h3>
|
|
||||||
<p id="creatorNpub" class="text-sm text-gray-400">npub...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Video Description -->
|
|
||||||
<div class="bg-gray-800 rounded-lg p-4 mb-4">
|
|
||||||
<p
|
|
||||||
id="videoDescription"
|
|
||||||
class="text-gray-300 whitespace-pre-wrap"
|
|
||||||
>
|
|
||||||
No description available.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Torrent stats -->
|
|
||||||
<div class="bg-gray-800 rounded-lg p-4">
|
|
||||||
<div class="w-full bg-gray-700 rounded-full h-2 mb-2">
|
|
||||||
<div
|
|
||||||
class="bg-blue-500 h-2 rounded-full"
|
|
||||||
id="modalProgress"
|
|
||||||
style="width: 0%"
|
|
||||||
></div>
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-between text-sm text-gray-400">
|
|
||||||
<span id="modalPeers">Peers: 0</span>
|
|
||||||
<span id="modalSpeed">Speed: 0 KB/s</span>
|
|
||||||
<span id="modalDownloaded">Downloaded: 0 MB / 0 MB</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="text-center mb-8">
|
<div class="text-center mb-8">
|
||||||
<h2 class="text-2xl font-bold text-gray-500 tracking-wide">
|
<h2 class="text-2xl font-bold text-gray-500 tracking-wide">
|
||||||
seed. zap. subscribe.
|
seed. zap. subscribe.
|
||||||
|
155
src/js/app.js
155
src/js/app.js
@@ -29,27 +29,21 @@ class bitvidApp {
|
|||||||
this.speed = document.getElementById("speed");
|
this.speed = document.getElementById("speed");
|
||||||
this.downloaded = document.getElementById("downloaded");
|
this.downloaded = document.getElementById("downloaded");
|
||||||
|
|
||||||
// Modal Elements
|
// Initialize these as null - they'll be set after modal loads
|
||||||
this.playerModal = document.getElementById("playerModal");
|
this.playerModal = null;
|
||||||
this.modalVideo = document.getElementById("modalVideo");
|
this.modalVideo = null;
|
||||||
this.modalStatus = document.getElementById("modalStatus");
|
this.modalStatus = null;
|
||||||
this.modalProgress = document.getElementById("modalProgress");
|
this.modalProgress = null;
|
||||||
this.modalPeers = document.getElementById("modalPeers");
|
this.modalPeers = null;
|
||||||
this.modalSpeed = document.getElementById("modalSpeed");
|
this.modalSpeed = null;
|
||||||
this.modalDownloaded = document.getElementById("modalDownloaded");
|
this.modalDownloaded = null;
|
||||||
this.closePlayerBtn = document.getElementById("closePlayer");
|
this.closePlayerBtn = null;
|
||||||
|
this.videoTitle = null;
|
||||||
// Video Info Elements
|
this.videoDescription = null;
|
||||||
this.videoTitle = document.getElementById("videoTitle");
|
this.videoTimestamp = null;
|
||||||
this.videoDescription = document.getElementById("videoDescription");
|
this.creatorAvatar = null;
|
||||||
this.videoTimestamp = document.getElementById("videoTimestamp");
|
this.creatorName = null;
|
||||||
|
this.creatorNpub = null;
|
||||||
// Creator Info Elements
|
|
||||||
this.creatorAvatar = document
|
|
||||||
.getElementById("creatorAvatar")
|
|
||||||
.querySelector("img");
|
|
||||||
this.creatorName = document.getElementById("creatorName");
|
|
||||||
this.creatorNpub = document.getElementById("creatorNpub");
|
|
||||||
|
|
||||||
// Notification Containers
|
// Notification Containers
|
||||||
this.errorContainer = document.getElementById("errorContainer");
|
this.errorContainer = document.getElementById("errorContainer");
|
||||||
@@ -58,21 +52,22 @@ class bitvidApp {
|
|||||||
this.pubkey = null;
|
this.pubkey = null;
|
||||||
this.currentMagnetUri = null;
|
this.currentMagnetUri = null;
|
||||||
|
|
||||||
// ADDED FOR VERSIONING/PRIVATE/DELETE:
|
// Private Video Checkbox
|
||||||
// If you created an <input type="checkbox" id="isPrivate" /> in your HTML form:
|
|
||||||
this.isPrivateCheckbox = document.getElementById("isPrivate");
|
this.isPrivateCheckbox = document.getElementById("isPrivate");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the application by setting up the Nostr client and loading videos.
|
|
||||||
*/
|
|
||||||
// app.js
|
|
||||||
async init() {
|
async init() {
|
||||||
try {
|
try {
|
||||||
// Hide and reset player states
|
// Hide and reset player states
|
||||||
this.playerSection.style.display = "none";
|
if (this.playerSection) {
|
||||||
this.playerModal.style.display = "none";
|
this.playerSection.style.display = "none";
|
||||||
this.currentMagnetUri = null;
|
}
|
||||||
|
|
||||||
|
// Initialize modal first
|
||||||
|
await this.initModal();
|
||||||
|
|
||||||
|
// Then update modal element references
|
||||||
|
this.updateModalElements();
|
||||||
|
|
||||||
// Initialize Nostr and check login
|
// Initialize Nostr and check login
|
||||||
await nostrClient.init();
|
await nostrClient.init();
|
||||||
@@ -82,7 +77,7 @@ class bitvidApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setupEventListeners();
|
this.setupEventListeners();
|
||||||
disclaimerModal.show(); // Add this line here
|
disclaimerModal.show();
|
||||||
await this.loadVideos();
|
await this.loadVideos();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Init failed:", error);
|
console.error("Init failed:", error);
|
||||||
@@ -90,6 +85,87 @@ class bitvidApp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async initModal() {
|
||||||
|
try {
|
||||||
|
console.log("Starting modal initialization...");
|
||||||
|
const response = await fetch("components/video-modal.html");
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! status: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const html = await response.text();
|
||||||
|
console.log("Modal HTML loaded successfully");
|
||||||
|
|
||||||
|
const modalContainer = document.getElementById("modalContainer");
|
||||||
|
if (!modalContainer) {
|
||||||
|
throw new Error("Modal container element not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
modalContainer.innerHTML = html;
|
||||||
|
console.log("Modal HTML inserted into DOM");
|
||||||
|
|
||||||
|
// Set up modal close handler
|
||||||
|
const closeButton = document.getElementById("closeModal");
|
||||||
|
if (!closeButton) {
|
||||||
|
throw new Error("Close button element not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
closeButton.addEventListener("click", () => {
|
||||||
|
this.hideModal();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set up scroll handler for nav show/hide
|
||||||
|
let lastScrollY = 0;
|
||||||
|
const modalNav = document.getElementById("modalNav");
|
||||||
|
const playerModal = document.getElementById("playerModal");
|
||||||
|
|
||||||
|
if (!modalNav || !playerModal) {
|
||||||
|
throw new Error("Modal navigation elements not found!");
|
||||||
|
}
|
||||||
|
|
||||||
|
playerModal.addEventListener("scroll", (e) => {
|
||||||
|
const currentScrollY = e.target.scrollTop;
|
||||||
|
const shouldShowNav =
|
||||||
|
currentScrollY <= lastScrollY || currentScrollY < 50;
|
||||||
|
modalNav.style.transform = shouldShowNav
|
||||||
|
? "translateY(0)"
|
||||||
|
: "translateY(-100%)";
|
||||||
|
lastScrollY = currentScrollY;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Modal initialization completed successfully");
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Modal initialization failed:", error);
|
||||||
|
// You might want to show this error to the user
|
||||||
|
this.showError(`Failed to initialize video player: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateModalElements() {
|
||||||
|
// Update Modal Elements
|
||||||
|
this.playerModal = document.getElementById("playerModal");
|
||||||
|
this.modalVideo = document.getElementById("modalVideo");
|
||||||
|
this.modalStatus = document.getElementById("modalStatus");
|
||||||
|
this.modalProgress = document.getElementById("modalProgress");
|
||||||
|
this.modalPeers = document.getElementById("modalPeers");
|
||||||
|
this.modalSpeed = document.getElementById("modalSpeed");
|
||||||
|
this.modalDownloaded = document.getElementById("modalDownloaded");
|
||||||
|
this.closePlayerBtn = document.getElementById("closeModal");
|
||||||
|
|
||||||
|
// Update Video Info Elements
|
||||||
|
this.videoTitle = document.getElementById("videoTitle");
|
||||||
|
this.videoDescription = document.getElementById("videoDescription");
|
||||||
|
this.videoTimestamp = document.getElementById("videoTimestamp");
|
||||||
|
|
||||||
|
// Update Creator Info Elements
|
||||||
|
this.creatorAvatar = document.getElementById("creatorAvatar");
|
||||||
|
this.creatorName = document.getElementById("creatorName");
|
||||||
|
this.creatorNpub = document.getElementById("creatorNpub");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a timestamp into a "time ago" format.
|
* Formats a timestamp into a "time ago" format.
|
||||||
*/
|
*/
|
||||||
@@ -324,9 +400,10 @@ class bitvidApp {
|
|||||||
* Loads and displays videos from Nostr.
|
* Loads and displays videos from Nostr.
|
||||||
*/
|
*/
|
||||||
async loadVideos() {
|
async loadVideos() {
|
||||||
|
console.log("Starting loadVideos...");
|
||||||
try {
|
try {
|
||||||
const videos = await nostrClient.fetchVideos();
|
const videos = await nostrClient.fetchVideos();
|
||||||
this.log("Fetched videos (raw):", videos);
|
console.log("Raw videos from nostrClient:", videos);
|
||||||
|
|
||||||
if (!videos) {
|
if (!videos) {
|
||||||
this.log("No videos received");
|
this.log("No videos received");
|
||||||
@@ -351,9 +428,9 @@ class bitvidApp {
|
|||||||
if (displayedVideos.length === 0) {
|
if (displayedVideos.length === 0) {
|
||||||
this.log("No valid videos found after filtering.");
|
this.log("No valid videos found after filtering.");
|
||||||
this.videoList.innerHTML = `
|
this.videoList.innerHTML = `
|
||||||
<p class="text-center text-gray-500">
|
<p class="text-center text-gray-500">
|
||||||
No public videos available yet. Be the first to upload one!
|
No public videos available yet. Be the first to upload one!
|
||||||
</p>`;
|
</p>`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,7 +448,7 @@ class bitvidApp {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Now render only the displayedVideos
|
// Now render only the displayedVideos
|
||||||
this.renderVideoList(displayedVideos);
|
await this.renderVideoList(displayedVideos);
|
||||||
this.log(`Rendered ${displayedVideos.length} videos successfully`);
|
this.log(`Rendered ${displayedVideos.length} videos successfully`);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.log("Failed to fetch videos:", error);
|
this.log("Failed to fetch videos:", error);
|
||||||
@@ -379,9 +456,9 @@ class bitvidApp {
|
|||||||
"An error occurred while loading videos. Please try again later."
|
"An error occurred while loading videos. Please try again later."
|
||||||
);
|
);
|
||||||
this.videoList.innerHTML = `
|
this.videoList.innerHTML = `
|
||||||
<p class="text-center text-gray-500">
|
<p class="text-center text-gray-500">
|
||||||
No videos available at the moment. Please try again later.
|
No videos available at the moment. Please try again later.
|
||||||
</p>`;
|
</p>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user