UNPKG

@microbitsclub/paywall-solid

Version:
145 lines (142 loc) 5.46 kB
import Cookies from 'js-cookie'; import { createContext, createEffect, Show, useContext } from 'solid-js'; import { createStore } from 'solid-js/store'; import { isServer, Portal } from 'solid-js/web'; import { PaywallPopoverContent } from './paywall-popopver-content'; import { stringifyUrl } from './stringify-url'; const createPopoverPaywall = (microbits) => { const [state, setState] = createStore({ microbits }); return { state, // selectPaywallById(paywallId: string) { // if (state.microbits === undefined) return; // state.microbits // .getPaywallById(paywallId) // .then(x => { // if ('ok' in x) { // setState('currentPaywall', { // id: x.ok.id, // price: x.ok.price, // contentUrl: x.ok.url, // }); // } else { // setState('currentPaywall', undefined); // } // }) // .catch(() => { // setState('currentPaywall', undefined); // }); // }, selectPaywallByContentUrl(contentUrl) { if (state.microbits === undefined) return; state.microbits .getPaywallByContentUrl(contentUrl) .then(x => { if ('ok' in x) { setState('currentPaywall', { id: x.ok.id, price: x.ok.price, contentUrl: x.ok.url, }); } else { setState('currentPaywall', undefined); } }) .catch(() => { setState('currentPaywall', undefined); }); }, closePaywall() { setState('currentPaywall', undefined); }, confirmPaywallPurchase() { if (state.microbits === undefined) return; if (state.currentPaywall === undefined) return; const { id, contentUrl } = state.currentPaywall; const userSessionId = Cookies.get('microbits.user_session'); console.log({ userSessionId, paywallId: id, contentUrl }); if (userSessionId === undefined) { const userSessionUrl = stringifyUrl({ domain: 'microbits.localhost', path: ['a', 'merchant-user-session'], query: { redirect: contentUrl, merchant: state.microbits.config.merchantId, }, }); const signInUrl = stringifyUrl({ domain: 'microbits.localhost', path: ['a', 'signin'], query: { redirect: userSessionUrl }, }); window.location.href = signInUrl; } /* if userSessionId is undefined: redirect to userSessionAcquire with signin bounce destination is contentUrl otherwise: make purchase request through merchant backend destination is contentUrl */ }, }; }; const microbitsContext = createContext(); export const usePopoverPaywall = () => { const ctx = useContext(microbitsContext); if (ctx === undefined) { throw Error('PopoverPaywallProvider not found'); } const { state, ...rest } = ctx; return [state, rest]; }; const { Provider } = microbitsContext; export const PopoverPaywallProvider = (props) => { const ctx = createPopoverPaywall(props.microbits); const popoverElement = isServer ? undefined : document.body; const handleConfirm = () => { ctx.confirmPaywallPurchase(); }; const handleCancel = () => { ctx.closePaywall(); }; let preserveBodyStyle; createEffect(() => { if (ctx.state.currentPaywall !== undefined) { preserveBodyStyle = { height: document.body.style.height, overflow: document.body.style.overflow, }; document.body.style.height = '100%'; document.body.style.overflow = 'hidden'; } else if (preserveBodyStyle !== undefined) { document.body.style.height = preserveBodyStyle.height; document.body.style.overflow = preserveBodyStyle.overflow; preserveBodyStyle = undefined; } }); return (<Provider value={ctx}> {props.children} <Portal mount={popoverElement}> <Show when={ctx.state.currentPaywall !== undefined}> <div style={{ position: 'fixed', 'box-sizing': 'border', top: 0, left: 0, width: '100vw', height: '100vh', opacity: 0.5, 'background-color': '#eee', }}/> </Show> <PaywallPopoverContent visible={ctx.state.currentPaywall !== undefined} paywallId={ctx.state.currentPaywall?.id} paywallPrice={ctx.state.currentPaywall?.price} onConfirm={handleConfirm} onCancel={handleCancel}/> </Portal> </Provider>); };