Files
bitvid/views/channel-profile.html
T
thePR0M3TH3ANandClaude Opus 4.8 cf82978060 zaps: profile-zap counting + channel "sats zapped" total (#47 — closes the feature)
The store now supports p: (profile/channel) pointers — every zap tagged to a
creator pubkey (direct profile zaps AND zaps to their videos, both carry a `p`
tag), from 9735 receipts + verified tallies:

- pointerKey accepts "p"; new profilePointer(pubkey) helper.
- runBatch batches p: pointers into a #p filter; both folds count #p-tagged
  events (deduped by payment_hash like a:/e:).
- Channel page: a "⚡ N sats zapped" total under the lightning address, wired
  to the store via js/channelZapTotal.js (own module for channelProfile.js's
  size budget), hidden until nonzero.

Completes the D2 video + profile scope; the bitvid-native zap tally feature is
now feature-complete (publish + count + chart + video + profile). Tests:
profilePointer/pointerKey + #p counting in tests/zap-totals.test.mjs. Lint
(size cap ok) + build green.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-05 00:36:44 -04:00

188 lines
6.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<section class="channel-profile-container" data-ds="new">
<!-- Modified banner wrapper for taller, rounded style -->
<div class="profile-banner relative mb-6 rounded-lg shadow-lg">
<!-- Increase the default height classes -->
<img
id="channelBanner"
class="h-48 w-full rounded-lg object-cover md:h-64"
src="assets/jpg/bitvid.jpg"
alt="Banner"
loading="lazy"
referrerpolicy="no-referrer"
data-fallback-src="assets/jpg/bitvid.jpg"
/>
<div class="pointer-events-none absolute inset-0 rounded-lg bg-overlay-channel"></div>
<div
class="absolute bottom-4 left-4 right-4 flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between"
>
<div class="flex flex-col gap-3">
<div
id="channelModerationBadge"
class="channel-moderation-badge-anchor"
aria-live="polite"
></div>
<div class="flex items-center">
<div
class="h-16 w-16 overflow-hidden rounded-full border-2 border-border-translucent-bright max-sm:h-12 max-sm:w-12"
>
<img
id="channelAvatar"
src="assets/svg/default-profile.svg"
alt="Avatar"
class="h-full w-full object-cover"
/>
</div>
<div class="ml-4 text-text">
<h2 id="channelName" class="text-xl font-bold max-sm:text-base">User Name</h2>
<p id="channelNpub" class="text-sm opacity-80 max-sm:text-2xs">npub...</p>
</div>
</div>
</div>
<div class="flex flex-col items-end gap-3 self-start sm:self-end">
<div class="flex items-center gap-2">
<button
id="zapButton"
type="button"
class="icon-button accent-action-button"
aria-label="Open zap dialog"
aria-haspopup="dialog"
aria-expanded="false"
aria-controls="zapControls"
>
<svg
class="icon-image"
viewBox="0 0 24 24"
aria-hidden="true"
focusable="false"
>
<polygon
points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
</button>
<button
id="channelMessageBtn"
type="button"
class="icon-button accent-action-button"
aria-label="Send message"
title="Send message"
>
<svg
class="icon-image"
viewBox="0 0 24 24"
aria-hidden="true"
focusable="false"
>
<path
fill="currentColor"
d="M4 4h16a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H9l-5 4v-4H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm0 2v9h1.5L7 14h13V6H4Zm2.5 2h11v2h-11V8Zm0 4h7v2h-7v-2Z"
/>
</svg>
</button>
<button
id="channelShareBtn"
type="button"
class="icon-button accent-action-button"
aria-label="Share channel"
>
<svg
class="icon-image"
viewBox="0 0 24 24"
aria-hidden="true"
focusable="false"
>
<path
fill="currentColor"
d="M5 7a5 5 0 1 1 0 10 5 5 0 0 1 0-10Zm11.122 12.065A4 4 0 1 1 24 20a4 4 0 0 1-7.878-.935l-5.488-2.927a6.009 6.009 0 0 1-.943 1.764l5.488 2.927ZM24 4a4 4 0 1 1-7.878.935l-5.488 2.927a6.01 6.01 0 0 1-.943-1.764l5.488-2.927A4 4 0 0 1 24 4Z"
/>
</svg>
</button>
<button
id="channelMoreBtn"
type="button"
class="icon-button accent-action-button"
aria-haspopup="true"
aria-expanded="false"
aria-label="Channel options"
aria-controls="channelProfileMoreMenu"
>
<svg
class="icon-image"
viewBox="0 0 24 24"
aria-hidden="true"
focusable="false"
>
<circle cx="5" cy="12" r="2" fill="currentColor" />
<circle cx="12" cy="12" r="2" fill="currentColor" />
<circle cx="19" cy="12" r="2" fill="currentColor" />
</svg>
</button>
</div>
</div>
</div>
</div>
<!-- Basic profile details: about text, website, LN address -->
<div class="profile-details mt-4 px-4">
<p id="channelAbout" class="mb-2 text-text-strong"></p>
<a
id="channelWebsite"
href="#"
target="_blank"
rel="noopener noreferrer"
class="mb-2 block text-info-strong hover:underline"
>Website</a
>
<p id="channelLightning" class="text-sm text-muted-strong"></p>
<!-- #47: total sats zapped to this creator (bitvid tallies + 9735s).
Hidden until there's a nonzero total. -->
<p
id="channelZapTotal"
class="text-sm text-zap font-medium hidden"
title="Total sats zapped to this creator via bitvid"
></p>
</div>
<!-- Area for Subscribe/Unsubscribe button -->
<div class="my-4 px-4">
<div id="subscribeBtnArea" class="hidden"></div>
</div>
<hr class="my-6" />
<div class="flex items-center gap-2 mb-4">
<h3 class="text-lg font-bold text-text-strong">Videos by This User</h3>
<button
type="button"
id="channelInfoTrigger"
class="text-muted hover:text-text focus:outline-none transition-colors"
aria-label="How is this feed sorted?"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="w-5 h-5"
aria-hidden="true"
>
<circle cx="12" cy="12" r="10"></circle>
<line x1="12" y1="16" x2="12" y2="12"></line>
<line x1="12" y1="8" x2="12.01" y2="8"></line>
</svg>
</button>
</div>
<div id="channelVideoList" class="bv-grid-video">
<!-- User’s videos will go here -->
</div>
</section>