<commit_before>import * as React from 'react'
import { ipcRenderer, remote } from 'electron'

import { RepositoriesList } from './repositories-list'
import { RepositoryView } from './repository'
import { WindowControls } from './window/window-controls'
import { Dispatcher, AppStore, CloningRepository } from '../lib/dispatcher'
import { Repository } from '../models/repository'
import { MenuEvent } from '../main-process/menu'
import { assertNever } from '../lib/fatal-error'
import { IAppState, RepositorySection, PopupType, FoldoutType, SelectionType } from '../lib/app-state'
import { Popuppy } from './popuppy'
import { CreateBranch } from './create-branch'
import { Branches } from './branches'
import { AddRepository } from './add-repository'
import { RenameBranch } from './rename-branch'
import { DeleteBranch } from './delete-branch'
import { PublishRepository } from './publish-repository'
import { CloningRepositoryView } from './cloning-repository'
import { Toolbar, ToolbarDropdown, DropdownState, PushPullButton } from './toolbar'
import { OcticonSymbol } from './octicons'
import { showPopupAppMenu, setMenuEnabled, setMenuVisible } from './main-process-proxy'
import { DiscardChanges } from './discard-changes'
import { updateStore, UpdateState } from './lib/update-store'
import { getDotComAPIEndpoint } from '../lib/api'
import { MenuIDs } from '../main-process/menu'
import { StatsStore, ILaunchStats } from '../lib/stats'
import { Welcome } from './welcome'
import { UpdateAvailable } from './updates'

/** The interval at which we should check for updates. */
const UpdateCheckInterval = 1000 * 60 * 60 * 4

const SendStatsInterval = 1000 * 60 * 60 * 4

interface IAppProps {
  readonly dispatcher: Dispatcher
  readonly appStore: AppStore
  readonly statsStore: StatsStore
}

export class App extends React.Component<IAppProps, IAppState> {
  public constructor(props: IAppProps) {
    super(props)

    this.state = props.appStore.getState()
    props.appStore.onDidUpdate(state => {
      this.setState(state)

      const selectedState = state.selectedState
      let haveBranch = false
      if (selectedState && selectedState.type === SelectionType.Repository) {
        const currentBranch = selectedState.state.branchesState.currentBranch
        const defaultBranch = selectedState.state.branchesState.defaultBranch
        // If we are:
        //  1. on the default branch, or
        //  2. on an unborn branch, or
        //  3. on a detached HEAD
        // there's not much we can do.
        if (!currentBranch || !defaultBranch || currentBranch.name === defaultBranch.name) {
          haveBranch = false
        } else {
          haveBranch = true
        }
      }

      setMenuEnabled('rename-branch', haveBranch)
      setMenuEnabled('delete-branch', haveBranch)
    })

    ipcRenderer.on('menu-event', (event: Electron.IpcRendererEvent, { name }: { name: MenuEvent }) => {
      this.onMenuEvent(name)
    })

    updateStore.onDidChange(state => {
      const visibleItem = (function () {
        switch (state) {
          case UpdateState.CheckingForUpdates: return 'checking-for-updates'
          case UpdateState.UpdateReady: return 'quit-and-install-update'
          case UpdateState.UpdateNotAvailable: return 'check-for-updates'
          case UpdateState.UpdateAvailable: return 'downloading-update'
        }

        return assertNever(state, `Unknown update state: ${state}`)
      })() as MenuIDs

      const menuItems = new Set([
        'checking-for-updates',
        'downloading-update',
        'check-for-updates',
        'quit-and-install-update',
      ]) as Set<MenuIDs>

      menuItems.delete(visibleItem)
      for (const item of menuItems) {
        setMenuVisible(item, false)
      }

      setMenuVisible(visibleItem, true)
    })<commit_msg>Show the popup once the update is ready<commit_after>import * as React from 'react'
import { ipcRenderer, remote } from 'electron'

import { RepositoriesList } from './repositories-list'
import { RepositoryView } from './repository'
import { WindowControls } from './window/window-controls'
import { Dispatcher, AppStore, CloningRepository } from '../lib/dispatcher'
import { Repository } from '../models/repository'
import { MenuEvent } from '../main-process/menu'
import { assertNever } from '../lib/fatal-error'
import { IAppState, RepositorySection, PopupType, FoldoutType, SelectionType } from '../lib/app-state'
import { Popuppy } from './popuppy'
import { CreateBranch } from './create-branch'
import { Branches } from './branches'
import { AddRepository } from './add-repository'
import { RenameBranch } from './rename-branch'
import { DeleteBranch } from './delete-branch'
import { PublishRepository } from './publish-repository'
import { CloningRepositoryView } from './cloning-repository'
import { Toolbar, ToolbarDropdown, DropdownState, PushPullButton } from './toolbar'
import { OcticonSymbol } from './octicons'
import { showPopupAppMenu, setMenuEnabled, setMenuVisible } from './main-process-proxy'
import { DiscardChanges } from './discard-changes'
import { updateStore, UpdateState } from './lib/update-store'
import { getDotComAPIEndpoint } from '../lib/api'
import { MenuIDs } from '../main-process/menu'
import { StatsStore, ILaunchStats } from '../lib/stats'
import { Welcome } from './welcome'
import { UpdateAvailable } from './updates'

/** The interval at which we should check for updates. */
const UpdateCheckInterval = 1000 * 60 * 60 * 4

const SendStatsInterval = 1000 * 60 * 60 * 4

interface IAppProps {
  readonly dispatcher: Dispatcher
  readonly appStore: AppStore
  readonly statsStore: StatsStore
}

export class App extends React.Component<IAppProps, IAppState> {
  public constructor(props: IAppProps) {
    super(props)

    this.state = props.appStore.getState()
    props.appStore.onDidUpdate(state => {
      this.setState(state)

      const selectedState = state.selectedState
      let haveBranch = false
      if (selectedState && selectedState.type === SelectionType.Repository) {
        const currentBranch = selectedState.state.branchesState.currentBranch
        const defaultBranch = selectedState.state.branchesState.defaultBranch
        // If we are:
        //  1. on the default branch, or
        //  2. on an unborn branch, or
        //  3. on a detached HEAD
        // there's not much we can do.
        if (!currentBranch || !defaultBranch || currentBranch.name === defaultBranch.name) {
          haveBranch = false
        } else {
          haveBranch = true
        }
      }

      setMenuEnabled('rename-branch', haveBranch)
      setMenuEnabled('delete-branch', haveBranch)
    })

    ipcRenderer.on('menu-event', (event: Electron.IpcRendererEvent, { name }: { name: MenuEvent }) => {
      this.onMenuEvent(name)
    })

    updateStore.onDidChange(state => {
      const visibleItem = (function () {
        switch (state) {
          case UpdateState.CheckingForUpdates: return 'checking-for-updates'
          case UpdateState.UpdateReady: return 'quit-and-install-update'
          case UpdateState.UpdateNotAvailable: return 'check-for-updates'
          case UpdateState.UpdateAvailable: return 'downloading-update'
        }

        return assertNever(state, `Unknown update state: ${state}`)
      })() as MenuIDs

      const menuItems = new Set([
        'checking-for-updates',
        'downloading-update',
        'check-for-updates',
        'quit-and-install-update',
      ]) as Set<MenuIDs>

      menuItems.delete(visibleItem)
      for (const item of menuItems) {
        setMenuVisible(item, false)
      }

      setMenuVisible(visibleItem, true)

      if (state === UpdateState.UpdateReady) {
        this.props.dispatcher.showPopup({ type: PopupType.UpdateAvailable })
      }
    })
{'fraction_non_alphanumeric': 0.11748878923766816, 'fraction_numerical': 0.0053811659192825115, 'mean_word_length': 3.2058189655172415, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '66012', 'n_tokens_mistral': 2223, 'n_tokens_neox': 2175, 'n_words': 585}