<commit_before>// Copyright (c) 2015-2016 <NAME>
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import fs from 'fs';
import path from 'path';

import {app, BrowserWindow, dialog, ipcMain, shell} from 'electron';

import logger from 'electron-log';
import {autoUpdater} from 'electron-updater';
import semver from 'semver';

const INTERVAL_48_HOURS_IN_MS = 5 * 60 * 1000; // 5 min.

autoUpdater.logger = logger;
autoUpdater.logger.transports.file.level = 'info';

let updaterModal = null;

function createEventListener(win, eventName) {
  return (event) => {
    if (event.sender === win.webContents) {
      win.emit(eventName);
    }
  };
}

function createUpdaterModal(parentWindow, options) {
  const windowWidth = 480;
  const windowHeight = 240;
  const windowOptions = {
    title: `${app.getName()} Updater`,
    parent: parentWindow,
    modal: true,
    maximizable: false,
    show: false,
    width: windowWidth,
    height: windowHeight,
    resizable: false,
    autoHideMenuBar: true,
  };
  if (process.platform === 'linux') {
    windowOptions.icon = options.linuxAppIcon;
  }

  const modal = new BrowserWindow(windowOptions);
  modal.once('ready-to-show', () => {
    modal.show();
  });
  let updaterURL = (global.isDev ? 'http://localhost:8080' : `file://${app.getAppPath()}`) + '/browser/updater.html';

  if (options.notifyOnly) {
    updaterURL += '?notifyOnly=true';
  }
  modal.loadURL(updaterURL);

  for (const eventName of ['click-release-notes', 'click-skip', 'click-remind', 'click-install', 'click-download']) {
    const listener = createEventListener(modal, eventName);
    ipcMain.on(eventName, listener);
    modal.on('closed', () => {
      ipcMain.removeListener(eventName, listener);
    });
  }

  return modal;
}

function isUpdateApplicable(now, skippedVersion, updateInfo) {
  const releaseTime = new Date(updateInfo.releaseDate).getTime();

  // 48 hours after a new version is added to releases.mattermost.com, user receives a “New update is available” dialog
  if (now.getTime() - releaseTime < INTERVAL_48_HOURS_IN_MS) {
    return false;
  }

  // If a version was skipped, compare version.
  if (skippedVersion) {
    return semver.gt(updateInfo.version, skippedVersion);
  }

  return true;
}

function downloadAndInstall() {
  autoUpdater.downloadUpdate().then(() => {
    autoUpdater.quitAndInstall();
  });
}

function initialize(appState, mainWindow, notifyOnly = false) {
  autoUpdater.autoDownload = false; // To prevent upgrading on quit
  const assetsDir = path.resolve(app.getAppPath(), 'assets');
  autoUpdater.on('error', (err) => {
    console.error('Error in autoUpdater:', err.message);
  }).on('update-available', (info) => {
    if (isUpdateApplicable(new Date(), appState.skippedVersion, info)) {
      updaterModal = createUpdaterModal(mainWindow, {
        linuxAppIcon: path.join(assetsDir, 'appicon.png'),
        notifyOnly,
      });
      updaterModal.on('closed', () => {
        updaterModal = null;
      });
      updaterModal.on('click-skip', () => {
        appState.skippedVersion = info.version;
        updaterModal.close();
      }).on('click-remind', () => {
        appState.updateCheckedDate = new Date();
        setTimeout(() => { // eslint-disable-line max-nested-callbacks
          autoUpdater.checkForUpdates();
        }, INTERVAL_48_HOURS_IN_MS);
        updaterModal.close();
      }).on('click-install', () => {
        updaterModal.webContents.send('start-download');
        autoUpdater.signals.progress((data) => { // eslint-disable-line max-nested-callbacks
          updaterModal.send('progress', Math.floor(data.percent));<commit_msg>Set flag to quit on auto-update<commit_after>// Copyright (c) 2015-2016 <NAME>
// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import fs from 'fs';
import path from 'path';

import {app, BrowserWindow, dialog, ipcMain, shell} from 'electron';

import logger from 'electron-log';
import {autoUpdater} from 'electron-updater';
import semver from 'semver';

const INTERVAL_48_HOURS_IN_MS = 5 * 60 * 1000; // 5 min.

autoUpdater.logger = logger;
autoUpdater.logger.transports.file.level = 'info';

let updaterModal = null;

function createEventListener(win, eventName) {
  return (event) => {
    if (event.sender === win.webContents) {
      win.emit(eventName);
    }
  };
}

function createUpdaterModal(parentWindow, options) {
  const windowWidth = 480;
  const windowHeight = 240;
  const windowOptions = {
    title: `${app.getName()} Updater`,
    parent: parentWindow,
    modal: true,
    maximizable: false,
    show: false,
    width: windowWidth,
    height: windowHeight,
    resizable: false,
    autoHideMenuBar: true,
  };
  if (process.platform === 'linux') {
    windowOptions.icon = options.linuxAppIcon;
  }

  const modal = new BrowserWindow(windowOptions);
  modal.once('ready-to-show', () => {
    modal.show();
  });
  let updaterURL = (global.isDev ? 'http://localhost:8080' : `file://${app.getAppPath()}`) + '/browser/updater.html';

  if (options.notifyOnly) {
    updaterURL += '?notifyOnly=true';
  }
  modal.loadURL(updaterURL);

  for (const eventName of ['click-release-notes', 'click-skip', 'click-remind', 'click-install', 'click-download']) {
    const listener = createEventListener(modal, eventName);
    ipcMain.on(eventName, listener);
    modal.on('closed', () => {
      ipcMain.removeListener(eventName, listener);
    });
  }

  return modal;
}

function isUpdateApplicable(now, skippedVersion, updateInfo) {
  const releaseTime = new Date(updateInfo.releaseDate).getTime();

  // 48 hours after a new version is added to releases.mattermost.com, user receives a “New update is available” dialog
  if (now.getTime() - releaseTime < INTERVAL_48_HOURS_IN_MS) {
    return false;
  }

  // If a version was skipped, compare version.
  if (skippedVersion) {
    return semver.gt(updateInfo.version, skippedVersion);
  }

  return true;
}

function downloadAndInstall() {
  autoUpdater.downloadUpdate().then(() => {
    global.willAppQuit = true;
    autoUpdater.quitAndInstall();
  });
}

function initialize(appState, mainWindow, notifyOnly = false) {
  autoUpdater.autoDownload = false; // To prevent upgrading on quit
  const assetsDir = path.resolve(app.getAppPath(), 'assets');
  autoUpdater.on('error', (err) => {
    console.error('Error in autoUpdater:', err.message);
  }).on('update-available', (info) => {
    if (isUpdateApplicable(new Date(), appState.skippedVersion, info)) {
      updaterModal = createUpdaterModal(mainWindow, {
        linuxAppIcon: path.join(assetsDir, 'appicon.png'),
        notifyOnly,
      });
      updaterModal.on('closed', () => {
        updaterModal = null;
      });
      updaterModal.on('click-skip', () => {
        appState.skippedVersion = info.version;
        updaterModal.close();
      }).on('click-remind', () => {
        appState.updateCheckedDate = new Date();
        setTimeout(() => { // eslint-disable-line max-nested-callbacks
          autoUpdater.checkForUpdates();
        }, INTERVAL_48_HOURS_IN_MS);
        updaterModal.close();
      }).on('click-install', () => {
        updaterModal.webContents.send('start-download');
        autoUpdater.signals.progress((data) => { // eslint-disable-line max-nested-callbacks
          updaterModal.send('progress', Math.floor(data.percent));
{'fraction_non_alphanumeric': 0.14598148396618812, 'fraction_numerical': 0.010197236012344022, 'mean_word_length': 3.6212027278363297, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4976194', 'n_tokens_mistral': 2413, 'n_tokens_neox': 2350, 'n_words': 506}