From f6c4b9f06c1e8e3142ed2428715ba18104e12d0d Mon Sep 17 00:00:00 2001 From: Dorian Date: Fri, 13 Feb 2026 20:48:58 +0000 Subject: [PATCH] Fix false "Rented" state for project owners + add "Your project" badge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The rental check catch block was incorrectly setting hasActiveRental=true for project owners when the API call failed (e.g. auth token not synced). This showed a "Rented" badge with no time remaining and hid the rent button. - Separate "owner can play" from "has active rental" via new isOwner computed - canPlay now includes isOwner so owners always have playback access - Catch block no longer fakes a rental — keeps the badge accurate - New purple "Your project" badge for owners (distinct from green "Rented") Co-authored-by: Cursor --- docker-compose.yml | 2 +- src/components/ContentDetailModal.vue | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index f912b9e..cc2e57f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,7 +20,7 @@ services: context: . dockerfile: Dockerfile args: - CACHEBUST: "10" + CACHEBUST: "11" VITE_USE_MOCK_DATA: "false" VITE_CONTENT_ORIGIN: ${FRONTEND_URL} VITE_INDEEHUB_API_URL: /api diff --git a/src/components/ContentDetailModal.vue b/src/components/ContentDetailModal.vue index bf87d9e..bfc14a5 100644 --- a/src/components/ContentDetailModal.vue +++ b/src/components/ContentDetailModal.vue @@ -43,6 +43,9 @@ Rented · {{ rentalTimeRemaining }} + + Your project + {{ content.rentalPrice.toLocaleString() }} sats @@ -274,6 +277,9 @@ const relayConnected = ref(true) const hasActiveRental = ref(false) const rentalExpiresAt = ref(null) +/** True if the logged-in user is the project owner */ +const isOwner = computed(() => !!props.content?.isOwnProject) + /** Human-readable time remaining on the rental (e.g. "23h 15m") */ const rentalTimeRemaining = computed(() => { if (!rentalExpiresAt.value) return '' @@ -285,9 +291,9 @@ const rentalTimeRemaining = computed(() => { return `${minutes}m remaining` }) -/** True when the user can play without paying (subscription or active rental) */ +/** True when the user can play without paying (subscription, active rental, or project owner) */ const canPlay = computed(() => - hasActiveSubscription.value || hasActiveRental.value, + hasActiveSubscription.value || hasActiveRental.value || isOwner.value, ) async function checkRentalAccess() { @@ -304,9 +310,10 @@ async function checkRentalAccess() { rentalExpiresAt.value = result.expiresAt ? new Date(result.expiresAt) : null } catch (err) { console.warn('Rental check failed:', err) - // If the rental check fails (e.g. auth issue) but the user owns the - // content, treat it as "can play" so the owner isn't blocked. - hasActiveRental.value = !!props.content.isOwnProject + // Owner playback is handled by the isOwner computed property, + // so we don't fake a rental here. This keeps the "Rented" badge + // accurate and still shows the rental price for non-owners. + hasActiveRental.value = false rentalExpiresAt.value = null } }