mirror of
https://github.com/PR0M3TH3AN/Artstr-Studio.git
synced 2026-11-05 21:20:40 +00:00
Premium unlock: refresh preview pane in place with a reveal flash
Previously, after clicking Unlock from the preview pane, the pane
kept showing the watermarked locked version until the user closed
and re-opened it. That made the "I just bought this" moment feel
inert, and could read as "did the payment work?" friction.
Now, on a successful unlock from openUnlockConfirm:
- Check if #nostrPreviewPanel is currently showing the row we
just unlocked (it stashes the row reference on the panel).
- If so, rebuild the row from _feedCache.events so it reflects
the freshly-decrypted payload (passes skipVersionFilter so the
cache stays fresh even for legacy version fields), and call
openDesignPreview(freshRow). The pane re-paints: the action
rail's "⚡ Unlock for N sats" swaps to "Use/Fork", the
watermarked JPEG body swaps to the real renderTemplate /
renderCustomArt etc. preview DOM, and Save JSON re-enables.
- Apply a new .premiumRevealFlash class to the panel right
after the swap. Defined as a 0.55 s premiumRevealFade
keyframe that fades from opacity 0 + 0.985 scale + slight
brightness boost to fully visible — reads as "the content
just appeared" without being garish.
Failure cases stay non-blocking: a try/catch around the preview
refresh logs to console without affecting the rest of the unlock
toast or the feed rerender.
Tested via CDP: synthetic premium event in the cache, open
preview pane (locked: watermarked image + Unlock CTA),
stub payZapSplit + upsertPurchaseVaultItem + native confirm so
openUnlockConfirm runs through. After the call returns the
preview pane has Use/Fork button, no JPEG image in the body, and
the premiumRevealFlash class set.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
This commit is contained in:
1 parent
191d216084
commit
99b386db54
1 file changed
+33
@@ -2113,6 +2113,15 @@
|
||||
background-image:linear-gradient(var(--panel),var(--panel)),linear-gradient(135deg,#ffd166 0%,#ef476f 50%,#06d6a0 100%);
|
||||
}
|
||||
.feedCard.feedCardPremium:hover{box-shadow:0 0 0 1px rgba(239,71,111,.20), 0 6px 22px rgba(239,71,111,.18)}
|
||||
/* Reveal animation when a premium design switches from locked to
|
||||
unlocked inside the preview pane — fades the new content in over the
|
||||
watermark with a subtle scale. */
|
||||
@keyframes premiumRevealFade {
|
||||
0% { opacity: 0; transform: scale(.985); filter: brightness(1.04); }
|
||||
60% { opacity: 1; transform: none; filter: brightness(1.04); }
|
||||
100% { opacity: 1; transform: none; filter: none; }
|
||||
}
|
||||
.premiumRevealFlash { animation: premiumRevealFade .55s ease-out; }
|
||||
.feedCardPremiumRibbon{
|
||||
position:absolute;top:6px;left:6px;z-index:7;
|
||||
font-size:.62rem;font-weight:800;letter-spacing:.04em;
|
||||
@@ -5709,6 +5718,30 @@
|
||||
if (typeof _currentFeedRerender === 'function') {
|
||||
try { _currentFeedRerender(); } catch {}
|
||||
}
|
||||
// If the user opened the preview pane for THIS design before clicking
|
||||
// unlock, refresh the pane to show the decrypted preview (instead of
|
||||
// the watermarked locked version) and flash the reveal animation.
|
||||
try {
|
||||
const previewedRow = $('nostrPreviewPanel')?._row;
|
||||
if (previewedRow?.e?.id === eventId) {
|
||||
const freshEvent = (_feedCache.events || []).find((ev) => ev.id === eventId) || row.e;
|
||||
const freshRows = buildRowsFromEvents([freshEvent], 'any', '', true);
|
||||
const freshRow = freshRows[0] || row;
|
||||
// openDesignPreview wipes #nostrPreviewPanel; refresh from the
|
||||
// updated cache state.
|
||||
openDesignPreview(freshRow);
|
||||
const panel = $('nostrPreviewPanel');
|
||||
if (panel) {
|
||||
panel.classList.remove('premiumRevealFlash');
|
||||
// Force reflow so the animation re-triggers if it had been
|
||||
// applied previously.
|
||||
void panel.offsetWidth;
|
||||
panel.classList.add('premiumRevealFlash');
|
||||
}
|
||||
}
|
||||
} catch (refreshErr) {
|
||||
console.warn('[unlock] preview refresh failed', refreshErr);
|
||||
}
|
||||
} catch (err) {
|
||||
if (statusToast?.dismiss) statusToast.dismiss();
|
||||
const msg = err?.message || 'Unlock failed.';
|
||||
|
||||
Reference in new issue
Block a user