<commit_before>import * as React from 'react'
import * as ReactDOM from 'react-dom'
import * as Path from 'path'
import * as Url from 'url'

import { ipcRenderer, remote } from 'electron'

import { App } from './app'
import { WindowState, getWindowState } from '../lib/window-state'
import { Dispatcher, AppStore, GitHubUserStore, GitHubUserDatabase, CloningRepositoriesStore, EmojiStore } from '../lib/dispatcher'
import { URLActionType } from '../lib/parse-url'
import { Repository } from '../models/repository'
import { getDefaultDir, setDefaultDir } from './lib/default-dir'
import { SelectionType } from '../lib/app-state'
import { sendReady } from './main-process-proxy'
import { reportError } from '../lib/exception-reporting'
import { getVersion } from './lib/app-proxy'
import { StatsDatabase, StatsStore } from '../lib/stats'
import { IssuesDatabase, IssuesStore, SignInStore } from '../lib/dispatcher'
import { requestAuthenticatedUser, resolveOAuthRequest, rejectOAuthRequest } from '../lib/oauth'
import { defaultErrorHandler, createMissingRepositoryHandler } from '../lib/dispatcher'

import { getLogger } from '../lib/logging/renderer'
import { installDevGlobals } from './install-globals'

if (__DEV__) {
  installDevGlobals()
}

const startTime = Date.now()

if (!process.env.TEST_ENV) {
  /* This is the magic trigger for webpack to go compile
  * our sass into css and inject it into the DOM. */
  require('../../styles/desktop.scss')
}

process.on('uncaughtException', (error: Error) => {
  getLogger().error('Uncaught exception on UI', error)
  reportError(error, getVersion())
})

const gitHubUserStore = new GitHubUserStore(new GitHubUserDatabase('GitHubUserDatabase'))
const cloningRepositoriesStore = new CloningRepositoriesStore()
const emojiStore = new EmojiStore()
const issuesStore = new IssuesStore(new IssuesDatabase('IssuesDatabase'))
const statsStore = new StatsStore(new StatsDatabase('StatsDatabase'))
const signInStore = new SignInStore()

const appStore = new AppStore(
  gitHubUserStore,
  cloningRepositoriesStore,
  emojiStore,
  issuesStore,
  statsStore,
  signInStore,
)

const dispatcher = new Dispatcher(appStore)
dispatcher.registerErrorHandler(defaultErrorHandler)
dispatcher.registerErrorHandler(createMissingRepositoryHandler(appStore))

dispatcher.loadInitialState().then(() => {
  const now = Date.now()
  sendReady(now - startTime)
})

document.body.classList.add(`platform-${process.platform}`)

function updateFullScreenBodyInfo(windowState: WindowState) {
  if (windowState === 'full-screen') {
    document.body.classList.add('fullscreen')
  } else {
    document.body.classList.remove('fullscreen')
  }
}

updateFullScreenBodyInfo(getWindowState(remote.getCurrentWindow()))
ipcRenderer.on('window-state-changed', (_, args) => updateFullScreenBodyInfo(args as WindowState))

ipcRenderer.on('focus', () => {
  const state = appStore.getState().selectedState
  if (!state || state.type !== SelectionType.Repository) { return }

  dispatcher.refreshRepository(state.repository)
})

ipcRenderer.on('blur', () => {
  // Make sure we stop highlighting the menu button (on non-macOS)
  // when someone uses Alt+Tab to switch application since we won't
  // get the onKeyUp event for the Alt key in that case.
  dispatcher.setAppMenuToolbarButtonHighlightState(false)
})

ipcRenderer.on('url-action', async (event: Electron.IpcRendererEvent, { action }: { action: URLActionType }) => {
  switch (action.name) {
    case 'oauth':
      try {
        const user = await requestAuthenticatedUser(action.args.code)
        if (user) {
          resolveOAuthRequest(user)
        } else {
          rejectOAuthRequest(new Error('Unable to fetch authenticated user.'))
        }
      } catch (e) {
        rejectOAuthRequest(e)
      }
      break

    case 'open-repository':
      const { url, branch } = action.args
      openRepository(url, branch)
      break

    default:
      console.log(`Unknown URL action: ${action.name} - payload: ${JSON.stringify(action)}`)
  }
})

function cloneRepository(url: string, branch?: string) {
  const cloneLocation = getDefaultDir()

  const defaultName = Path.basename(Url.parse(url)!.path!, '.git')
  const path: string | null = remote.dialog.showSaveDialog({
    buttonLabel: 'Clone',
    defaultPath: Path.join(cloneLocation, defaultName),
  })
  if (!path) { return }

  setDefaultDir(Path.resolve(path, '..'))

  const state = appStore.getState()

  // TODO: This isn't quite right. We should probably get the user from the
  // context or URL or something.
  const user = state.users[0]

  const clonePromise = dispatcher.clone(url, path, { user, branch })

  if (!branch) { return clonePromise }

  return clonePromise.then(repository => {
    if (!repository) { return }

    return dispatcher.checkoutBranch(repository, branch)
  })
}

function openRepository(url: string, branch?: string) {
  const state = appStore.getState()
  const repositories = state.repositories
  const existingRepository = repositories.find(r => {<commit_msg>no need for the chaining of promises now<commit_after>import * as React from 'react'
import * as ReactDOM from 'react-dom'
import * as Path from 'path'
import * as Url from 'url'

import { ipcRenderer, remote } from 'electron'

import { App } from './app'
import { WindowState, getWindowState } from '../lib/window-state'
import { Dispatcher, AppStore, GitHubUserStore, GitHubUserDatabase, CloningRepositoriesStore, EmojiStore } from '../lib/dispatcher'
import { URLActionType } from '../lib/parse-url'
import { Repository } from '../models/repository'
import { getDefaultDir, setDefaultDir } from './lib/default-dir'
import { SelectionType } from '../lib/app-state'
import { sendReady } from './main-process-proxy'
import { reportError } from '../lib/exception-reporting'
import { getVersion } from './lib/app-proxy'
import { StatsDatabase, StatsStore } from '../lib/stats'
import { IssuesDatabase, IssuesStore, SignInStore } from '../lib/dispatcher'
import { requestAuthenticatedUser, resolveOAuthRequest, rejectOAuthRequest } from '../lib/oauth'
import { defaultErrorHandler, createMissingRepositoryHandler } from '../lib/dispatcher'

import { getLogger } from '../lib/logging/renderer'
import { installDevGlobals } from './install-globals'

if (__DEV__) {
  installDevGlobals()
}

const startTime = Date.now()

if (!process.env.TEST_ENV) {
  /* This is the magic trigger for webpack to go compile
  * our sass into css and inject it into the DOM. */
  require('../../styles/desktop.scss')
}

process.on('uncaughtException', (error: Error) => {
  getLogger().error('Uncaught exception on UI', error)
  reportError(error, getVersion())
})

const gitHubUserStore = new GitHubUserStore(new GitHubUserDatabase('GitHubUserDatabase'))
const cloningRepositoriesStore = new CloningRepositoriesStore()
const emojiStore = new EmojiStore()
const issuesStore = new IssuesStore(new IssuesDatabase('IssuesDatabase'))
const statsStore = new StatsStore(new StatsDatabase('StatsDatabase'))
const signInStore = new SignInStore()

const appStore = new AppStore(
  gitHubUserStore,
  cloningRepositoriesStore,
  emojiStore,
  issuesStore,
  statsStore,
  signInStore,
)

const dispatcher = new Dispatcher(appStore)
dispatcher.registerErrorHandler(defaultErrorHandler)
dispatcher.registerErrorHandler(createMissingRepositoryHandler(appStore))

dispatcher.loadInitialState().then(() => {
  const now = Date.now()
  sendReady(now - startTime)
})

document.body.classList.add(`platform-${process.platform}`)

function updateFullScreenBodyInfo(windowState: WindowState) {
  if (windowState === 'full-screen') {
    document.body.classList.add('fullscreen')
  } else {
    document.body.classList.remove('fullscreen')
  }
}

updateFullScreenBodyInfo(getWindowState(remote.getCurrentWindow()))
ipcRenderer.on('window-state-changed', (_, args) => updateFullScreenBodyInfo(args as WindowState))

ipcRenderer.on('focus', () => {
  const state = appStore.getState().selectedState
  if (!state || state.type !== SelectionType.Repository) { return }

  dispatcher.refreshRepository(state.repository)
})

ipcRenderer.on('blur', () => {
  // Make sure we stop highlighting the menu button (on non-macOS)
  // when someone uses Alt+Tab to switch application since we won't
  // get the onKeyUp event for the Alt key in that case.
  dispatcher.setAppMenuToolbarButtonHighlightState(false)
})

ipcRenderer.on('url-action', async (event: Electron.IpcRendererEvent, { action }: { action: URLActionType }) => {
  switch (action.name) {
    case 'oauth':
      try {
        const user = await requestAuthenticatedUser(action.args.code)
        if (user) {
          resolveOAuthRequest(user)
        } else {
          rejectOAuthRequest(new Error('Unable to fetch authenticated user.'))
        }
      } catch (e) {
        rejectOAuthRequest(e)
      }
      break

    case 'open-repository':
      const { url, branch } = action.args
      openRepository(url, branch)
      break

    default:
      console.log(`Unknown URL action: ${action.name} - payload: ${JSON.stringify(action)}`)
  }
})

function cloneRepository(url: string, branch?: string) {
  const cloneLocation = getDefaultDir()

  const defaultName = Path.basename(Url.parse(url)!.path!, '.git')
  const path: string | null = remote.dialog.showSaveDialog({
    buttonLabel: 'Clone',
    defaultPath: Path.join(cloneLocation, defaultName),
  })
  if (!path) { return }

  setDefaultDir(Path.resolve(path, '..'))

  const state = appStore.getState()

  // TODO: This isn't quite right. We should probably get the user from the
  // context or URL or something.
  const user = state.users[0]

  return dispatcher.clone(url, path, { user, branch })
}

function openRepository(url: string, branch?: string) {
  const state = appStore.getState()
  const repositories = state.repositories
  const existingRepository = repositories.find(r => {
{'fraction_non_alphanumeric': 0.12547989492826833, 'fraction_numerical': 0.00020206102242877348, 'mean_word_length': 4.385745375408052, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 18, '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': '5859487', 'n_tokens_mistral': 2927, 'n_tokens_neox': 2866, 'n_words': 748}