import { ButtonPrimary } from "components/Buttons"; import { Popover } from "components/Popover"; import { MenuItem } from "components/Menu"; import { Separator } from "components/Layout"; import { useUIState } from "src/useUIState"; import { useState } from "react"; import { useSmoker, useToaster } from "components/Toast"; import { BlockProps, BlockLayout } from "./Block"; import { useEntity, useReplicache } from "src/replicache"; import { useEntitySetContext } from "components/EntitySetProvider"; import { subscribeToMailboxWithEmail } from "actions/subscriptions/subscribeToMailboxWithEmail"; import { confirmEmailSubscription } from "actions/subscriptions/confirmEmailSubscription"; import { focusPage } from "src/utils/focusPage"; import { v7 } from "uuid"; import { sendPostToSubscribers } from "actions/subscriptions/sendPostToSubscribers"; import { getBlocksWithType } from "src/hooks/queries/useBlocks"; import { getBlocksAsHTML } from "src/utils/getBlocksAsHTML"; import { htmlToMarkdown } from "src/htmlMarkdownParsers"; import { addSubscription, removeSubscription, unsubscribe, useSubscriptionStatus, } from "src/hooks/useSubscriptionStatus"; import { usePageTitle } from "components/utils/UpdateLeafletTitle"; import { ArrowDownTiny } from "components/Icons/ArrowDownTiny"; import { InfoSmall } from "components/Icons/InfoSmall"; export const MailboxBlock = ( props: BlockProps & { areYouSure?: boolean; setAreYouSure?: (value: boolean) => void; }, ) => { let isSubscribed = useSubscriptionStatus(props.entityID); let isSelected = useUIState((s) => s.selectedBlocks.find((b) => b.value === props.entityID), ); let permission = useEntitySetContext().permissions.write; let { rep } = useReplicache(); let smoke = useSmoker(); let draft = useEntity(props.entityID, "mailbox/draft"); let entity_set = useEntitySetContext(); let subscriber_count = useEntity(props.entityID, "mailbox/subscriber-count"); if (!permission) return ( ); return (
{ let entity; if (draft) { entity = draft.data.value; } else { entity = v7(); await rep?.mutate.createDraft({ mailboxEntity: props.entityID, permission_set: entity_set.set, newEntity: entity, firstBlockEntity: v7(), firstBlockFactID: v7(), }); } useUIState.getState().openPage(props.parent, entity); if (rep) focusPage(entity, rep, "focusFirstBlock"); return; }} > {draft ? "Edit Draft" : "Write a Post"}
{ <> {!isSubscribed?.confirmed ? ( ) : ( )}
{!subscriber_count || subscriber_count?.data.value === undefined || subscriber_count?.data.value === 0 ? "no" : subscriber_count?.data.value}{" "} reader {subscriber_count?.data.value === 1 ? "" : "s"}
}
); }; const MailboxReaderView = (props: { entityID: string; parent: string; }) => { let isSubscribed = useSubscriptionStatus(props.entityID); let isSelected = useUIState((s) => s.selectedBlocks.find((b) => b.value === props.entityID), ); let archive = useEntity(props.entityID, "mailbox/archive"); let smoke = useSmoker(); let { rep } = useReplicache(); return (
{!isSubscribed?.confirmed ? ( <> ) : (
You're Subscribed!
{archive ? ( { e.preventDefault(); if (rep) { useUIState .getState() .openPage(props.parent, archive.data.value); focusPage(archive.data.value, rep); } }} > See All Posts ) : (
Nothing has been posted yet
)}
)}
); }; const MailboxInfo = (props: { subscriber?: boolean }) => { return ( } >
{props.subscriber ? ( <>

Get a notification whenever the creator posts to this mailbox!

Your contact info will be kept private, and you can unsubscribe anytime.

) : ( <>

When you post to this mailbox, subscribers will be notified!

Reader contact info is kept private.

You can have one draft post at a time.

)}
); }; const SubscribePopover = (props: { entityID: string; parent: string; unconfirmed: boolean; }) => { return ( {props.unconfirmed ? "Confirm" : "Subscribe"} } >
); }; const SubscribeForm = (props: { entityID: string; parent: string; role: "author" | "reader"; compact?: boolean; }) => { let smoke = useSmoker(); let [channel, setChannel] = useState<"email" | "sms">("email"); let [email, setEmail] = useState(""); let [sms, setSMS] = useState(""); let subscription = useSubscriptionStatus(props.entityID); let [code, setCode] = useState(""); let { permission_token } = useReplicache(); if (subscription && !subscription.confirmed) { return (
Enter the code we sent to{" "} {subscription.email} {" "} here!
{ e.preventDefault(); let result = await confirmEmailSubscription( subscription.id, code, ); let rect = document .getElementById("confirm-code-button") ?.getBoundingClientRect(); if (!result) { smoke({ error: true, text: "oops, incorrect code", position: { x: rect ? rect.left + 45 : 0, y: rect ? rect.top + 15 : 0, }, }); return; } addSubscription(result.subscription); }} className="mailboxConfirmCodeInput flex gap-2 items-center mx-auto" > setCode(e.currentTarget.value)} /> Confirm!
); } return ( <>
{ e.preventDefault(); let subscriptionID = await subscribeToMailboxWithEmail( props.entityID, email, permission_token, ); if (subscriptionID) addSubscription(subscriptionID); }} className={`mailboxSubscribeForm flex sm:flex-row flex-col ${props.compact && "sm:flex-col sm:gap-2"} gap-2 sm:gap-3 items-center place-self-center mx-auto`} >
setEmail(e.target.value)} className="w-full appearance-none focus:outline-hidden bg-transparent" placeholder="youremail@email.com" />
Subscribe!
{props.role === "reader" && ( )}
); }; const GoToArchive = (props: { entityID: string; parent: string; small?: boolean; }) => { let archive = useEntity(props.entityID, "mailbox/archive"); let { rep } = useReplicache(); return archive ? ( ) : (
no posts yet
); };