<commit_before>import * as React from 'react'
import * as ConfigGen from '../actions/config-gen'
import {Box2} from './box'
import Icon from './icon'
import Button, {Props as ButtonProps} from './button'
import Text from './text'
import Toast from './toast'
import {useTimeout} from './use-timers'
import * as Styles from '../styles'
import * as Container from '../util/container'

type Props = {
  buttonType?: ButtonProps['type']
  containerStyle?: Styles.StylesCrossPlatform
  multiline?: boolean | number
  onCopy?: () => void
  hideOnCopy?: boolean
  onReveal?: () => void
  withReveal?: boolean
  text?: string
  placeholderText?: string
  loadText?: () => void
}

const CopyText = (props: Props) => {
  const [revealed, setRevealed] = React.useState(!props.withReveal)
  const [showingToast, setShowingToast] = React.useState(false)
  const [requestedCopy, setRequestedCopy] = React.useState(false)
  const setShowingToastFalseLater = useTimeout(() => setShowingToast(false), 1500)
  React.useEffect(() => {
    showingToast && setShowingToastFalseLater()
  }, [showingToast, setShowingToastFalseLater])

  React.useEffect(() => {
    if (!props.withReveal && !props.text) {
      // only try to load text if withReveal is false
      if (!props.loadText) {
        throw new Error('no loadText method provided')
      }
      props.loadText()
    }
  }, []) // only run this effect once, on first render

  const attachmentRef = React.useRef<Box2>(null)
  const textRef = React.useRef<Text>(null)

  const dispatch = Container.useDispatch()
  const copyToClipboard = (text: string) => dispatch(ConfigGen.createCopyToClipboard({text}))

  const copy = () => {
    if (!props.text) {
      if (!props.loadText) {
        throw new Error('no text to copy and no loadText method provided')
      }
      setRequestedCopy(true)
    } else {
      setShowingToast(true)
      textRef.current && textRef.current.highlightText()
      copyToClipboard(props.text)
      props.onCopy && props.onCopy()
      if (props.hideOnCopy) {
        setRevealed(false)
      }
    }
  }

  React.useEffect(() => {
    if (requestedCopy && props.loadText) {
      // we're requesting a copy
      if (!props.text) {
        // no text has been loaded
        props.loadText()
      } else {
        // we want to copy something + have something to copy<commit_msg>fix crash on master (#20127)<commit_after>import * as React from 'react'
import * as ConfigGen from '../actions/config-gen'
import {Box2} from './box'
import Icon from './icon'
import Button, {Props as ButtonProps} from './button'
import Text from './text'
import Toast from './toast'
import {useTimeout} from './use-timers'
import * as Styles from '../styles'
import * as Container from '../util/container'

type Props = {
  buttonType?: ButtonProps['type']
  containerStyle?: Styles.StylesCrossPlatform
  multiline?: boolean | number
  onCopy?: () => void
  hideOnCopy?: boolean
  onReveal?: () => void
  withReveal?: boolean
  text?: string
  placeholderText?: string
  loadText?: () => void
}

const CopyText = (props: Props) => {
  const [revealed, setRevealed] = React.useState(!props.withReveal)
  const [showingToast, setShowingToast] = React.useState(false)
  const [requestedCopy, setRequestedCopy] = React.useState(false)
  const setShowingToastFalseLater = useTimeout(() => setShowingToast(false), 1500)
  React.useEffect(() => {
    showingToast && setShowingToastFalseLater()
  }, [showingToast, setShowingToastFalseLater])

  React.useEffect(() => {
    if (!props.withReveal && !props.text) {
      // only try to load text if withReveal is false
      props.loadText && props.loadText()
    }
  }, []) // only run this effect once, on first render

  const attachmentRef = React.useRef<Box2>(null)
  const textRef = React.useRef<Text>(null)

  const dispatch = Container.useDispatch()
  const copyToClipboard = (text: string) => dispatch(ConfigGen.createCopyToClipboard({text}))

  const copy = () => {
    if (!props.text) {
      if (!props.loadText) {
        return
      }
      setRequestedCopy(true)
    } else {
      setShowingToast(true)
      textRef.current && textRef.current.highlightText()
      copyToClipboard(props.text)
      props.onCopy && props.onCopy()
      if (props.hideOnCopy) {
        setRevealed(false)
      }
    }
  }

  React.useEffect(() => {
    if (requestedCopy && props.loadText) {
      // we're requesting a copy
      if (!props.text) {
        // no text has been loaded
        props.loadText()
      } else {
        // we want to copy something + have something to copy
{'fraction_non_alphanumeric': 0.1331005891337552, 'fraction_numerical': 0.0037093606807767836, 'mean_word_length': 3.2721342031686858, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1064763', 'n_tokens_mistral': 1450, 'n_tokens_neox': 1418, 'n_words': 374}