feat(app): improve payment and paywall UX
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
* - 点击空白 / 下滑手势 → 关闭
|
||||
* - 双指缩放(CSS `touch-action: pinch-zoom`)
|
||||
*/
|
||||
import { ChevronLeft } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
import { useEffect } from "react";
|
||||
|
||||
@@ -16,10 +17,17 @@ import styles from "./fullscreen-image-viewer.module.css";
|
||||
|
||||
export interface FullscreenImageViewerProps {
|
||||
imageUrl: string;
|
||||
imagePaywalled?: boolean;
|
||||
onUnlockImagePaywall?: () => void;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export function FullscreenImageViewer({ imageUrl, onClose }: FullscreenImageViewerProps) {
|
||||
export function FullscreenImageViewer({
|
||||
imageUrl,
|
||||
imagePaywalled = false,
|
||||
onUnlockImagePaywall,
|
||||
onClose,
|
||||
}: FullscreenImageViewerProps) {
|
||||
useEffect(() => {
|
||||
const handleKey = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") onClose();
|
||||
@@ -28,6 +36,44 @@ export function FullscreenImageViewer({ imageUrl, onClose }: FullscreenImageView
|
||||
return () => document.removeEventListener("keydown", handleKey);
|
||||
}, [onClose]);
|
||||
|
||||
const src = imageUrl.startsWith("data:") || imageUrl.startsWith("http")
|
||||
? imageUrl
|
||||
: `data:image/png;base64,${imageUrl}`;
|
||||
|
||||
if (imagePaywalled) {
|
||||
return (
|
||||
<div
|
||||
className={`${styles.viewer} ${styles.paywallViewer}`}
|
||||
role="dialog"
|
||||
aria-label="Locked fullscreen image"
|
||||
>
|
||||
<Image
|
||||
src={src}
|
||||
alt=""
|
||||
fill
|
||||
sizes="100vw"
|
||||
className={styles.paywallImage}
|
||||
/>
|
||||
<div className={styles.paywallScrim} aria-hidden="true" />
|
||||
<button
|
||||
type="button"
|
||||
className={styles.backButton}
|
||||
onClick={onClose}
|
||||
aria-label="Back"
|
||||
>
|
||||
<ChevronLeft size={34} strokeWidth={2.5} aria-hidden="true" />
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className={styles.unlockButton}
|
||||
onClick={onUnlockImagePaywall}
|
||||
>
|
||||
Unlock high-definition large image
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={styles.viewer}
|
||||
@@ -36,7 +82,7 @@ export function FullscreenImageViewer({ imageUrl, onClose }: FullscreenImageView
|
||||
aria-label="Fullscreen image"
|
||||
>
|
||||
<Image
|
||||
src={imageUrl.startsWith("data:") || imageUrl.startsWith("http") ? imageUrl : `data:image/png;base64,${imageUrl}`}
|
||||
src={src}
|
||||
alt=""
|
||||
width={800}
|
||||
height={800}
|
||||
|
||||
Reference in New Issue
Block a user