feat: artwork share system with modal, native Web Share API, and tracking
- Add ArtworkShareModal with glassmorphism UI (Facebook, X, Pinterest, Email, Copy Link, Embed Code)
- Add ArtworkShareButton with lazy-loaded modal and native share fallback
- Add useWebShare hook abstracting navigator.share with AbortError handling
- Add ShareToast auto-dismissing notification component
- Add share() endpoint to ArtworkInteractionController (POST /api/artworks/{id}/share)
- Add artwork_shares migration for Phase 2 share tracking
- Refactor ArtworkActionBar to use new ArtworkShareButton component
This commit is contained in:
41
resources/js/hooks/useWebShare.js
Normal file
41
resources/js/hooks/useWebShare.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { useCallback, useMemo } from 'react'
|
||||
|
||||
/**
|
||||
* useWebShare – abstracts native Web Share API with a fallback callback.
|
||||
*
|
||||
* Usage:
|
||||
* const { canNativeShare, share } = useWebShare({ onFallback })
|
||||
* share({ title, text, url })
|
||||
*
|
||||
* If `navigator.share` is available the browser-native share sheet opens.
|
||||
* Otherwise `onFallback({ title, text, url })` is called (e.g. open a modal).
|
||||
*/
|
||||
export default function useWebShare({ onFallback } = {}) {
|
||||
const canNativeShare = useMemo(
|
||||
() => typeof navigator !== 'undefined' && typeof navigator.share === 'function',
|
||||
[],
|
||||
)
|
||||
|
||||
const share = useCallback(
|
||||
async ({ title, text, url }) => {
|
||||
if (canNativeShare) {
|
||||
try {
|
||||
await navigator.share({ title, text, url })
|
||||
return { shared: true, native: true }
|
||||
} catch (err) {
|
||||
// User cancelled the native share — don't fall through to modal
|
||||
if (err?.name === 'AbortError') {
|
||||
return { shared: false, native: true }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback — open modal
|
||||
onFallback?.({ title, text, url })
|
||||
return { shared: false, native: false }
|
||||
},
|
||||
[canNativeShare, onFallback],
|
||||
)
|
||||
|
||||
return { canNativeShare, share }
|
||||
}
|
||||
Reference in New Issue
Block a user