import { CopyToClipboard } from "react-copy-to-clipboard"; import { useFormState } from "react-use-form-state"; import { Flex } from "reflexbox/styled-components"; import React, { useState } from "react"; import styled from "styled-components"; import getConfig from "next/config"; import { useStoreActions, useStoreState } from "../store"; import { Checkbox, Select, TextInput } from "./Input"; import { Col, RowCenterH, RowCenter } from "./Layout"; import { useMessage, useCopy } from "../hooks"; import { removeProtocol } from "../utils"; import Text, { H1, Span } from "./Text"; import { Link } from "../store/links"; import Animation from "./Animation"; import { Colors } from "../consts"; import Icon from "./Icon"; const { publicRuntimeConfig } = getConfig(); const SubmitIconWrapper = styled.div` content: ""; position: absolute; top: 0; right: 12px; width: 64px; height: 100%; display: flex; justify-content: center; align-items: center; cursor: pointer; :hover svg { fill: #673ab7; } @media only screen and (max-width: 448px) { right: 8px; width: 40px; } `; const ShortenedLink = styled(H1)` cursor: "pointer"; border-bottom: 1px dotted ${Colors.StatsTotalUnderline}; cursor: pointer; :hover { opacity: 0.8; } `; interface Form { target: string; domain?: string; customurl?: string; password?: string; description?: string; expire_in?: string; showAdvanced?: boolean; } const defaultDomain = publicRuntimeConfig.DEFAULT_DOMAIN; const Shortener = () => { const { isAuthenticated } = useStoreState(s => s.auth); const domains = useStoreState(s => s.settings.domains); const submit = useStoreActions(s => s.links.submit); const [link, setLink] = useState(null); const [message, setMessage] = useMessage(3000); const [loading, setLoading] = useState(false); const [copied, setCopied] = useCopy(); const [formState, { raw, password, text, select, label }] = useFormState< Form >( { showAdvanced: false }, { withIds: true, onChange(e, stateValues, nextStateValues) { if (stateValues.showAdvanced && !nextStateValues.showAdvanced) { formState.clear(); formState.setField("target", stateValues.target); } } } ); const submitLink = async (reCaptchaToken?: string) => { try { const link = await submit({ ...formState.values, reCaptchaToken }); setLink(link); formState.clear(); } catch (err) { setMessage( err?.response?.data?.error || "Couldn't create the short link." ); } setLoading(false); }; const onSubmit = async e => { e.preventDefault(); if (loading) return; setCopied(false); setLoading(true); if ( process.env.NODE_ENV === "production" && !!publicRuntimeConfig.RECAPTCHA_SITE_KEY && !isAuthenticated ) { window.grecaptcha.execute(window.captchaId); const getCaptchaToken = () => { setTimeout(() => { if (window.isCaptchaReady) { const reCaptchaToken = window.grecaptcha.getResponse( window.captchaId ); window.isCaptchaReady = false; window.grecaptcha.reset(window.captchaId); return submitLink(reCaptchaToken); } return getCaptchaToken(); }, 200); }; return getCaptchaToken(); } return submitLink(); }; const title = !link && (