~exprez135/mailspring-libre

22867f1a3e7d2bdd2839f4602c6880eec412ee2c — Ben Gotow 3 years ago 479fb44
Fix auto-fixable errors identified by the new versions of Typescript + ESLint
72 files changed, 117 insertions(+), 117 deletions(-)

M app/internal_packages/account-sidebar/lib/sidebar-section.ts
M app/internal_packages/account-sidebar/lib/sidebar-store.ts
M app/internal_packages/activity/lib/dashboard/root.tsx
M app/internal_packages/activity/lib/dashboard/share-button.tsx
M app/internal_packages/category-mapper/lib/category-selection.tsx
M app/internal_packages/composer-signature/lib/signature-photo-picker.tsx
M app/internal_packages/composer/lib/composer-view.tsx
M app/internal_packages/contacts/lib/Store.ts
M app/internal_packages/events/lib/event-header.tsx
M app/internal_packages/main-calendar/lib/core/calendar-data-source.ts
M app/internal_packages/main-calendar/lib/core/week-view.tsx
M app/internal_packages/main-calendar/lib/event-description-frame.tsx
M app/internal_packages/message-list/lib/email-frame.tsx
M app/internal_packages/mode-switch/lib/mode-toggle.tsx
M app/internal_packages/onboarding/lib/newsletter-signup.tsx
M app/internal_packages/onboarding/lib/oauth-signin-page.tsx
M app/internal_packages/preferences/lib/tabs/config-schema-item.tsx
M app/internal_packages/preferences/lib/tabs/preferences-identity.tsx
M app/internal_packages/preferences/lib/tabs/workspace-section.tsx
M app/internal_packages/send-reminders/lib/send-reminders-utils.ts
M app/internal_packages/thread-list/lib/thread-list-columns.tsx
M app/internal_packages/thread-list/lib/thread-list-participants.tsx
M app/internal_packages/thread-snooze/lib/snooze-popover.tsx
M app/internal_packages/translation/lib/message-header.tsx
M app/internal_packages/translation/lib/service.ts
M app/internal_packages/undo-redo/lib/undo-redo-toast.tsx
M app/src/app-env.ts
M app/src/browser/application-menu.ts
M app/src/browser/config-persistence-manager.ts
M app/src/components/billing-modal.tsx
M app/src/components/composer-editor/base-block-plugins.tsx
M app/src/components/composer-editor/composer-editor-toolbar.tsx
M app/src/components/composer-editor/conversion.tsx
M app/src/components/composer-editor/emoji-toolbar-popover.tsx
M app/src/components/date-input.tsx
M app/src/components/decorators/has-tutorial-tip.tsx
M app/src/components/empty-list-state.tsx
M app/src/components/evented-iframe.tsx
M app/src/components/injected-component-set.tsx
M app/src/components/key-commands-region.tsx
M app/src/components/mail-important-icon.tsx
M app/src/components/menu.tsx
M app/src/components/modal.tsx
M app/src/components/scroll-region.tsx
M app/src/components/time-picker.tsx
M app/src/components/tokenizing-text-field.tsx
M app/src/components/webview.tsx
M app/src/config.ts
M app/src/decorators/inflates-draft-client-id.tsx
M app/src/dom-utils.ts
M app/src/flux/models/utils.ts
M app/src/flux/stores/contact-store.ts
M app/src/flux/stores/database-store.ts
M app/src/flux/stores/draft-editing-session.ts
M app/src/flux/stores/feature-usage-store.tsx
M app/src/flux/stores/message-store.ts
M app/src/flux/stores/workspace-store.ts
M app/src/intl.ts
M app/src/keymap-manager.ts
M app/src/linux-theme-utils.ts
M app/src/mailbox-perspective.ts
M app/src/mailsync-process.ts
M app/src/menu-helpers.ts
M app/src/quickpreview/index.ts
M app/src/registries/command-registry.ts
M app/src/registries/component-registry.ts
M app/src/services/quoted-html-transformer.ts
M app/src/services/sanitize-transformer.ts
M app/src/services/search/search-query-parser.ts
M app/src/sheet-container.tsx
M app/src/sheet-toolbar.tsx
M app/src/theme-manager.ts
M app/internal_packages/account-sidebar/lib/sidebar-section.ts => app/internal_packages/account-sidebar/lib/sidebar-section.ts +1 -1
@@ 194,7 194,7 @@ class SidebarSection {
    //
    const items = [];
    const seenItems = {};
    for (let category of CategoryStore.userCategories(account)) {
    for (const category of CategoryStore.userCategories(account)) {
      // https://regex101.com/r/jK8cC2/1
      var item, parentKey;
      const re = RegExpUtils.subcategorySplitRegex();

M app/internal_packages/account-sidebar/lib/sidebar-store.ts => app/internal_packages/account-sidebar/lib/sidebar-store.ts +1 -1
@@ 87,7 87,7 @@ class SidebarStore extends MailspringStore {
  _onSetCollapsedByName = (itemName: string, collapsed: boolean) => {
    let item = this.standardSection().items.find(i => i.name === itemName);
    if (!item) {
      for (let section of this.userSections()) {
      for (const section of this.userSections()) {
        item = _.findWhere(section.items, { name: itemName });
        if (item) {
          break;

M app/internal_packages/activity/lib/dashboard/root.tsx => app/internal_packages/activity/lib/dashboard/root.tsx +2 -2
@@ 84,7 84,7 @@ class RootWithTimespan extends React.Component<
    accountIds: PropTypes.arrayOf(PropTypes.string),
  };

  _mounted: boolean = false;
  _mounted = false;

  constructor(props) {
    super(props);


@@ 234,7 234,7 @@ class RootWithTimespan extends React.Component<
    }

    // Aggregate open/link tracking of outbound threads by subject line
    let bySubject: { [subject: string]: SubjectStatsEntry } = {};
    const bySubject: { [subject: string]: SubjectStatsEntry } = {};
    for (const stats of outboundThreadStats) {
      if (!stats.tracked) {
        continue;

M app/internal_packages/activity/lib/dashboard/share-button.tsx => app/internal_packages/activity/lib/dashboard/share-button.tsx +1 -1
@@ 40,7 40,7 @@ function buildShareHTML(htmlEl, styleEl) {
}

export default class ShareButton extends React.Component<{}, { link: string; loading: boolean }> {
  _mounted: boolean = false;
  _mounted = false;
  _linkEl: HTMLInputElement;

  constructor(props) {

M app/internal_packages/category-mapper/lib/category-selection.tsx => app/internal_packages/category-mapper/lib/category-selection.tsx +2 -2
@@ 46,8 46,8 @@ export default class CategorySelection extends React.Component<
  _itemsForCategories(): CategoryItem[] {
    return this.props.all
      .sort((a, b) => {
        var pathA = utf7.imap.decode(a.path).toUpperCase();
        var pathB = utf7.imap.decode(b.path).toUpperCase();
        const pathA = utf7.imap.decode(a.path).toUpperCase();
        const pathB = utf7.imap.decode(b.path).toUpperCase();
        if (pathA < pathB) {
          return -1;
        }

M app/internal_packages/composer-signature/lib/signature-photo-picker.tsx => app/internal_packages/composer-signature/lib/signature-photo-picker.tsx +1 -1
@@ 74,7 74,7 @@ export default class SignaturePhotoPicker extends React.Component<
    const img = new Image();
    img.onload = () => {
      let scale = Math.min(MAX_IMAGE_RES / img.width, MAX_IMAGE_RES / img.height, 1);
      let scaleDesired = scale;
      const scaleDesired = scale;
      let source: any = img;

      let times = 0;

M app/internal_packages/composer/lib/composer-view.tsx => app/internal_packages/composer/lib/composer-view.tsx +1 -1
@@ 56,7 56,7 @@ export default class ComposerView extends React.Component<ComposerViewProps, Com
    className: PropTypes.string,
  };

  _mounted: boolean = false;
  _mounted = false;
  _mouseDownTarget: HTMLElement = null;

  dropzone = React.createRef<DropZone>();

M app/internal_packages/contacts/lib/Store.ts => app/internal_packages/contacts/lib/Store.ts +2 -2
@@ 17,7 17,7 @@ class ContactsWindowStore extends MailspringStore {
  _contactsSubscription: MutableQuerySubscription<Contact>;
  _groups: ContactGroup[] = [];
  _books: ContactBook[] = [];
  _search: string = '';
  _search = '';
  _filtered: Contact[] | null = null;
  _editing: string | 'new' | false = false;



@@ 84,7 84,7 @@ class ContactsWindowStore extends MailspringStore {
  }

  setPerspective(perspective: ContactsPerspective) {
    let q = DatabaseStore.findAll<Contact>(Contact)
    const q = DatabaseStore.findAll<Contact>(Contact)
      .where(Contact.attributes.refs.greaterThan(0))
      .where(Contact.attributes.hidden.equal(false));


M app/internal_packages/events/lib/event-header.tsx => app/internal_packages/events/lib/event-header.tsx +1 -1
@@ 53,7 53,7 @@ export class EventHeader extends React.Component<EventHeaderProps, EventHeaderSt
    inflight: undefined,
  };

  _mounted: boolean = false;
  _mounted = false;
  _subscription: Rx.IDisposable;

  componentWillUnmount() {

M app/internal_packages/main-calendar/lib/core/calendar-data-source.ts => app/internal_packages/main-calendar/lib/core/calendar-data-source.ts +1 -1
@@ 9,7 9,7 @@ export default class CalendarDataSource {
    const end = Event.attributes.recurrenceEnd;
    const start = Event.attributes.recurrenceStart;

    let matcher = new Matcher.Or([
    const matcher = new Matcher.Or([
      new Matcher.And([start.lte(endTime), end.gte(startTime)]),
      new Matcher.And([start.lte(endTime), start.gte(startTime)]),
      new Matcher.And([end.gte(startTime), end.lte(endTime)]),

M app/internal_packages/main-calendar/lib/core/week-view.tsx => app/internal_packages/main-calendar/lib/core/week-view.tsx +1 -1
@@ 59,7 59,7 @@ export default class WeekView extends React.Component<
  };

  _waitingForShift = 0;
  _mounted: boolean = false;
  _mounted = false;
  _sub?: Disposable;
  _lastWrapHeight: number;


M app/internal_packages/main-calendar/lib/event-description-frame.tsx => app/internal_packages/main-calendar/lib/event-description-frame.tsx +1 -1
@@ 10,7 10,7 @@ export default class EmailFrame extends React.Component<{ content: string }> {
    content: PropTypes.string.isRequired,
  };

  _mounted: boolean = false;
  _mounted = false;
  _unlisten?: () => void;
  _iframeComponent: EventedIFrame;
  _iframeHeightHolderEl: HTMLDivElement;

M app/internal_packages/message-list/lib/email-frame.tsx => app/internal_packages/message-list/lib/email-frame.tsx +2 -2
@@ 21,12 21,12 @@ export default class EmailFrame extends React.Component<EmailFrameProps> {
    showQuotedText: PropTypes.bool,
  };

  _mounted: boolean = false;
  _mounted = false;
  _unlisten: () => void;
  _iframeComponent: EventedIFrame;
  _iframeWrapperEl: HTMLDivElement;
  _iframeDocObserver: ResizeObserver;
  _lastFitSize: string = '';
  _lastFitSize = '';

  componentDidMount() {
    this._mounted = true;

M app/internal_packages/mode-switch/lib/mode-toggle.tsx => app/internal_packages/mode-switch/lib/mode-toggle.tsx +1 -1
@@ 5,7 5,7 @@ import React from 'react';
export default class ModeToggle extends React.Component<{}, { hidden: boolean }> {
  static displayName = 'ModeToggle';

  _mounted: boolean = false;
  _mounted = false;
  _unsubscriber: () => void;
  column = WorkspaceStore.Location.MessageListSidebar;


M app/internal_packages/onboarding/lib/newsletter-signup.tsx => app/internal_packages/onboarding/lib/newsletter-signup.tsx +1 -1
@@ 23,7 23,7 @@ export default class NewsletterSignup extends React.Component<
    emailAddress: PropTypes.string,
  };

  _mounted: boolean = false;
  _mounted = false;

  constructor(props) {
    super(props);

M app/internal_packages/onboarding/lib/oauth-signin-page.tsx => app/internal_packages/onboarding/lib/oauth-signin-page.tsx +1 -1
@@ 47,7 47,7 @@ export default class OAuthSignInPage extends React.Component<
  _server?: http.Server;
  _startTimer: NodeJS.Timeout;
  _warnTimer: NodeJS.Timeout;
  _mounted: boolean = false;
  _mounted = false;

  state: OAuthSignInPageState = {
    authStage: 'initial',

M app/internal_packages/preferences/lib/tabs/config-schema-item.tsx => app/internal_packages/preferences/lib/tabs/config-schema-item.tsx +1 -1
@@ 53,7 53,7 @@ class ConfigSchemaItem extends React.Component<ConfigSchemaItemProps> {
    // In the future, we may add an option to reveal "advanced settings"
    if (this.props.configSchema.advanced) return false;

    let note = this.props.configSchema.note ? (
    const note = this.props.configSchema.note ? (
      <div className="platform-note">{this.props.configSchema.note}</div>
    ) : null;


M app/internal_packages/preferences/lib/tabs/preferences-identity.tsx => app/internal_packages/preferences/lib/tabs/preferences-identity.tsx +1 -1
@@ 15,7 15,7 @@ class RefreshButton extends React.Component<{}, { refreshing: boolean }> {
    this.state = { refreshing: false };
  }

  _mounted: boolean = false;
  _mounted = false;

  componentDidMount() {
    this._mounted = true;

M app/internal_packages/preferences/lib/tabs/workspace-section.tsx => app/internal_packages/preferences/lib/tabs/workspace-section.tsx +1 -1
@@ 15,7 15,7 @@ const helper = new DefaultClientHelper();
const service = new SystemStartService();

class DefaultMailClientItem extends React.Component<{}, DefaultMailClientItemState> {
  _mounted: boolean = false;
  _mounted = false;

  state: DefaultMailClientItemState = { defaultClient: helper.available() ? false : 'unknown' };


M app/internal_packages/send-reminders/lib/send-reminders-utils.ts => app/internal_packages/send-reminders/lib/send-reminders-utils.ts +1 -1
@@ 90,7 90,7 @@ export async function findMessage({ accountId, headerMessageId }) {

export async function transferReminderMetadataFromDraftToThread({ accountId, headerMessageId }) {
  let message = await findMessage({ accountId, headerMessageId });
  let delay = [1500, 1500, 10000, 10000];
  const delay = [1500, 1500, 10000, 10000];

  // The sent message should already be synced, but if the send taks was interrupted and completed
  // without finalizing / cleaning up, we may need to go through a sync cycle. Do this before giving up.

M app/internal_packages/thread-list/lib/thread-list-columns.tsx => app/internal_packages/thread-list/lib/thread-list-columns.tsx +1 -1
@@ 16,7 16,7 @@ import ThreadListIcon from './thread-list-icon';

// Get and format either last sent or last received timestamp depending on thread-list being viewed
const ThreadListTimestamp = function({ thread }) {
  let rawTimestamp = FocusedPerspectiveStore.current().isSent()
  const rawTimestamp = FocusedPerspectiveStore.current().isSent()
    ? thread.lastMessageSentTimestamp
    : thread.lastMessageReceivedTimestamp;
  const timestamp = rawTimestamp ? DateUtils.shortTimeString(rawTimestamp) : localized('No Date');

M app/internal_packages/thread-list/lib/thread-list-participants.tsx => app/internal_packages/thread-list/lib/thread-list-participants.tsx +1 -1
@@ 108,7 108,7 @@ class ThreadListParticipants extends React.Component<{ thread: ThreadWithMessage
        continue;
      }

      for (let contact of message[field]) {
      for (const contact of message[field]) {
        if (tokens.length === 0) {
          tokens.push({ contact, unread: message.unread });
        } else {

M app/internal_packages/thread-snooze/lib/snooze-popover.tsx => app/internal_packages/thread-snooze/lib/snooze-popover.tsx +1 -1
@@ 44,7 44,7 @@ class SnoozePopover extends Component<{
    swipeCallback: () => {},
  };

  didSnooze: boolean = false;
  didSnooze = false;

  componentWillUnmount() {
    this.props.swipeCallback(this.didSnooze);

M app/internal_packages/translation/lib/message-header.tsx => app/internal_packages/translation/lib/message-header.tsx +2 -2
@@ 71,8 71,8 @@ export class TranslateMessageHeader extends React.Component<
> {
  static displayName = 'TranslateMessageHeader';

  _mounted: boolean = false;
  _detectionStarted: boolean = false;
  _mounted = false;
  _detectionStarted = false;

  state: TranslateMessageHeaderState = {
    detected: null,

M app/internal_packages/translation/lib/service.ts => app/internal_packages/translation/lib/service.ts +2 -2
@@ 184,13 184,13 @@ function forEachTranslatableText(doc: Document, callback: (el: Node, text: strin
// We maintain a cache of blocks of text we've translated. Because the user may have a whole
// mailbox of very similar or templated emails, this can cut down on the amount of text we
// need to translate for a new email dramatically.
let translatedSnippetCache = new LRU<string, string>({ max: 1000 });
const translatedSnippetCache = new LRU<string, string>({ max: 1000 });
let translatedSnippetLang = '';

export async function translateMessageBody(
  html: string,
  targetLang?: string,
  silent: boolean = false
  silent = false
): Promise<string | false> {
  if (translatedSnippetLang !== targetLang) {
    translatedSnippetCache.reset();

M app/internal_packages/undo-redo/lib/undo-redo-toast.tsx => app/internal_packages/undo-redo/lib/undo-redo-toast.tsx +1 -1
@@ 52,7 52,7 @@ class Countdown extends React.Component<{ expiration: number }, { x: number }> {

  render() {
    // subtract a few ms so we never round up to start time + 1 by accident
    let diff = Math.min(
    const diff = Math.min(
      Math.max(0, this.props.expiration - Date.now()),
      AppEnv.config.get('core.sending.undoSend')
    );

M app/src/app-env.ts => app/src/app-env.ts +5 -5
@@ 401,11 401,11 @@ export default class AppEnvConstructor {
  // Extended: Move current window to the center of the screen.
  center() {
    if (process.platform === 'linux') {
      let dimensions = this.getWindowDimensions();
      let display =
      const dimensions = this.getWindowDimensions();
      const display =
        remote.screen.getDisplayMatching(dimensions) || remote.screen.getPrimaryDisplay();
      let x = display.bounds.x + (display.bounds.width - dimensions.width) / 2;
      let y = display.bounds.y + (display.bounds.height - dimensions.height) / 2;
      const x = display.bounds.x + (display.bounds.width - dimensions.width) / 2;
      const y = display.bounds.y + (display.bounds.height - dimensions.height) / 2;

      return this.setPosition(x, y);
    } else {


@@ 849,7 849,7 @@ export default class AppEnvConstructor {

  restoreWindowState() {
    try {
      let stateString = window.localStorage.getItem(this.getWindowStateKey());
      const stateString = window.localStorage.getItem(this.getWindowStateKey());
      if (stateString != null) {
        this.savedState = JSON.parse(stateString);
      }

M app/src/browser/application-menu.ts => app/src/browser/application-menu.ts +2 -2
@@ 118,7 118,7 @@ export default class ApplicationMenu {
  // Returns an Array of native menu items.
  flattenMenuTemplate(template) {
    let items = [];
    for (let item of template) {
    for (const item of template) {
      items.push(item);
      if (item.submenu) {
        items = items.concat(this.flattenMenuTemplate(item.submenu));


@@ 132,7 132,7 @@ export default class ApplicationMenu {
  // enable - If true enables all window specific items, if false disables all
  //          window specific items.
  enableWindowSpecificItems(enable) {
    for (let item of this.flattenMenuItems(this.menu)) {
    for (const item of this.flattenMenuItems(this.menu)) {
      if (item.metadata && item.metadata['windowSpecific']) {
        item.enabled = enable;
      }

M app/src/browser/config-persistence-manager.ts => app/src/browser/config-persistence-manager.ts +2 -2
@@ 36,8 36,8 @@ export default class ConfigPersistenceManager {
    }

    try {
      let stat = fs.statSync(this.configDirPath);
      let configDirPathAccessMode = (stat.mode & parseInt('777', 8)).toString(8);
      const stat = fs.statSync(this.configDirPath);
      const configDirPathAccessMode = (stat.mode & parseInt('777', 8)).toString(8);
      if (configDirPathAccessMode !== '700') {
        fs.chmodSync(this.configDirPath, '700');
      }

M app/src/components/billing-modal.tsx => app/src/components/billing-modal.tsx +1 -1
@@ 16,7 16,7 @@ export default class BillingModal extends React.Component<BillingModalProps, Bil
  static IntrinsicWidth = 412;
  static IntrinsicHeight = 540;

  _mounted: boolean = false;
  _mounted = false;
  _initialZoom: number;

  constructor(props) {

M app/src/components/composer-editor/base-block-plugins.tsx => app/src/components/composer-editor/base-block-plugins.tsx +3 -3
@@ 15,7 15,7 @@ function nodeIsEmpty(node: Node) {
  }

  if (node.object !== 'text') {
    let children = ((node.nodes.toArray ? node.nodes.toArray() : node.nodes) || []) as any;
    const children = ((node.nodes.toArray ? node.nodes.toArray() : node.nodes) || []) as any;
    if (children.length === 0) {
      return true;
    }


@@ 132,7 132,7 @@ export const BLOCK_CONFIG: {
        } else {
          const value = editor.value;
          // Collect all the text fragments which are being converted to a code block
          let texts = value.document
          const texts = value.document
            .getTextsAtRange(value.selection as any)
            .toArray()
            .map(t => {


@@ 258,7 258,7 @@ const rules = [

      // div elements that are entirely empty and have no meaningful-looking styles applied
      // would probably just add extra whitespace
      let empty = !el.hasChildNodes();
      const empty = !el.hasChildNodes();
      if (tagName === 'div' && empty) {
        const s = (el.getAttribute('style') || '').toLowerCase();
        if (!s.includes('background') && !s.includes('margin') && !s.includes('padding')) {

M app/src/components/composer-editor/composer-editor-toolbar.tsx => app/src/components/composer-editor/composer-editor-toolbar.tsx +4 -4
@@ 16,8 16,8 @@ export default class ComposerEditorToolbar extends React.Component<
  ComposerEditorToolbarProps,
  ComposerEditorToolbarState
> {
  _mounted: boolean = false;
  _topClip: number = 0;
  _mounted = false;
  _topClip = 0;
  _el: HTMLElement;
  _floatingEl: HTMLElement;
  _heightObserver: ResizeObserver;


@@ 63,7 63,7 @@ export default class ComposerEditorToolbar extends React.Component<

  _onScroll = () => {
    if (!this._el) return;
    let { top, height } = this._el.getBoundingClientRect();
    const { top, height } = this._el.getBoundingClientRect();
    const max = this._el.parentElement.clientHeight - height;

    if (top < this._topClip) {


@@ 78,7 78,7 @@ export default class ComposerEditorToolbar extends React.Component<
  render() {
    const { editor, plugins, value } = this.props;

    let sectionItems = [];
    const sectionItems = [];

    if (!this.state.visible) {
      return (

M app/src/components/composer-editor/conversion.tsx => app/src/components/composer-editor/conversion.tsx +1 -1
@@ 261,7 261,7 @@ on the result. */
  };

  return mark.nodes.reduce(function(nodes, node) {
    var ret = applyMark(node);
    const ret = applyMark(node);
    if (Array.isArray(ret)) return nodes.concat(ret);
    nodes.push(ret);
    return nodes;

M app/src/components/composer-editor/emoji-toolbar-popover.tsx => app/src/components/composer-editor/emoji-toolbar-popover.tsx +1 -1
@@ 41,7 41,7 @@ export default class EmojiToolbarPopover extends React.Component<
  static displayName = 'EmojiToolbarPopover';

  _canvasEl: HTMLCanvasElement;
  _mounted: boolean = false;
  _mounted = false;
  _emojiPreloadImage = new Image();

  constructor(props) {

M app/src/components/date-input.tsx => app/src/components/date-input.tsx +1 -1
@@ 28,7 28,7 @@ class DateInput extends Component<DateInputProps, DateInputState> {
    onDateSubmitted: () => {},
  };

  _mounted: boolean = false;
  _mounted = false;

  constructor(props) {
    super(props);

M app/src/components/decorators/has-tutorial-tip.tsx => app/src/components/decorators/has-tutorial-tip.tsx +1 -1
@@ 126,7 126,7 @@ export default function HasTutorialTip(ComposedComponent, TipConfig) {

    _workspaceTimer?: NodeJS.Timeout;
    _themesTimer?: NodeJS.Timeout;
    _mounted: boolean = false;
    _mounted = false;
    _disposables: Disposable[];
    _unlisteners = [];


M app/src/components/empty-list-state.tsx => app/src/components/empty-list-state.tsx +2 -2
@@ 128,7 128,7 @@ class EmptyListState extends React.Component<
  static displayName = 'EmptyListState';
  static propTypes = { visible: PropTypes.bool.isRequired };

  _mounted: boolean = false;
  _mounted = false;
  _unlisteners = [];

  constructor(props) {


@@ 163,7 163,7 @@ class EmptyListState extends React.Component<

  componentWillUnmount() {
    this._mounted = false;
    for (let unlisten of Array.from(this._unlisteners)) {
    for (const unlisten of Array.from(this._unlisteners)) {
      unlisten();
    }
  }

M app/src/components/evented-iframe.tsx => app/src/components/evented-iframe.tsx +2 -2
@@ 236,7 236,7 @@ export class EventedIFrame extends React.Component<
    const nodeRect = node.getBoundingClientRect();

    const eventAttrs = {};
    for (let key of Object.keys(event)) {
    for (const key of Object.keys(event)) {
      if (['webkitMovementX', 'webkitMovementY'].includes(key)) {
        continue;
      }


@@ 362,7 362,7 @@ export class EventedIFrame extends React.Component<
        new MenuItem({
          label: localized('Copy Image'),
          click() {
            let img = new Image();
            const img = new Image();
            img.addEventListener(
              'load',
              function() {

M app/src/components/injected-component-set.tsx => app/src/components/injected-component-set.tsx +1 -1
@@ 87,7 87,7 @@ export class InjectedComponentSet extends React.Component<
    containersRequired: true,
  };

  _mounted: boolean = false;
  _mounted = false;
  _componentUnlistener?: () => void;

  constructor(props, context) {

M app/src/components/key-commands-region.tsx => app/src/components/key-commands-region.tsx +2 -2
@@ 117,11 117,11 @@ export class KeyCommandsRegion extends React.Component<

  _lastFocusElement: HTMLElement = null;
  _losingFocusToElement: HTMLElement = null;
  _losingFocusFrames: number = 0;
  _losingFocusFrames = 0;
  _lostFocusToElement: HTMLElement = null;
  _localDisposable?: Disposable;
  _globalDisposable?: Disposable;
  _goingout: boolean = false;
  _goingout = false;

  state = {
    focused: false,

M app/src/components/mail-important-icon.tsx => app/src/components/mail-important-icon.tsx +1 -1
@@ 47,7 47,7 @@ class MailImportantIcon extends React.Component<MailImportantIconProps, MailImpo

    if (props.showIfAvailableForAnyAccount) {
      const perspective = FocusedPerspectiveStore.current();
      for (let accountId of perspective.accountIds) {
      for (const accountId of perspective.accountIds) {
        const account = AccountStore.accountForId(accountId);
        const accountImportant = CategoryStore.getCategoryByRole(account, 'important');
        if (accountImportant) {

M app/src/components/menu.tsx => app/src/components/menu.tsx +1 -1
@@ 202,7 202,7 @@ export class Menu extends React.Component<MenuProps, MenuState> {

  static defaultProps = { onEscape() {} };

  _mounted: boolean = false;
  _mounted = false;

  constructor(props) {
    super(props);

M app/src/components/modal.tsx => app/src/components/modal.tsx +1 -1
@@ 25,7 25,7 @@ class Modal extends React.Component<ModalProps, ModalState> {
    width: PropTypes.number,
  };

  _mounted: boolean = false;
  _mounted = false;

  state = {
    offset: 0,

M app/src/components/scroll-region.tsx => app/src/components/scroll-region.tsx +1 -1
@@ 280,7 280,7 @@ export class ScrollRegion extends React.Component<
  // Concept from https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableView_Class/#//apple_ref/c/tdef/UITableViewScrollPosition
  static Scrollbar = Scrollbar;

  _mounted: boolean = false;
  _mounted = false;
  _scrollToTaskId = 0;
  _scrollbarComponent = null;
  _totalHeightObserver = null;

M app/src/components/time-picker.tsx => app/src/components/time-picker.tsx +1 -1
@@ 36,7 36,7 @@ export default class TimePicker extends React.Component<TimePickerProps, TimePic
    onChange: () => {},
  };

  _gotoScrollStartOnUpdate: boolean = false;
  _gotoScrollStartOnUpdate = false;

  constructor(props) {
    super(props);

M app/src/components/tokenizing-text-field.tsx => app/src/components/tokenizing-text-field.tsx +1 -1
@@ 422,7 422,7 @@ export class TokenizingTextField extends React.Component<
    tokenClassNames: () => '',
  };

  _mounted: boolean = false;
  _mounted = false;

  constructor(props) {
    super(props);

M app/src/components/webview.tsx => app/src/components/webview.tsx +1 -1
@@ 92,7 92,7 @@ type WebviewState = {
export default class Webview extends React.Component<WebviewProps, WebviewState> {
  static displayName = 'Webview';

  _mounted: boolean = false;
  _mounted = false;
  _disposable?: Disposable;

  state: WebviewState = {

M app/src/config.ts => app/src/config.ts +14 -14
@@ 291,9 291,9 @@ export default class Config {
  }

  static addSchemaEnforcers(filters) {
    for (var typeName in filters) {
      var functions = filters[typeName];
      for (let name in functions) {
    for (const typeName in filters) {
      const functions = filters[typeName];
      for (const name in functions) {
        const enforcerFunction = functions[name];
        this.addSchemaEnforcer(typeName, enforcerFunction);
      }


@@ 306,10 306,10 @@ export default class Config {
    if (!Array.isArray(types)) {
      types = [types];
    }
    for (let type of types) {
    for (const type of types) {
      try {
        const enforcerFunctions = this.schemaEnforcers[type].concat(this.schemaEnforcers['*']);
        for (let enforcer of enforcerFunctions) {
        for (const enforcer of enforcerFunctions) {
          // At some point in one's life, one must call upon an enforcer.
          value = enforcer.call(this, keyPath, value, schema);
        }


@@ 492,7 492,7 @@ export default class Config {
  getSchema(keyPath) {
    const keys = splitKeyPath(keyPath);
    let { schema } = this;
    for (let key of keys) {
    for (const key of keys) {
      if (schema == null) {
        break;
      }


@@ 575,7 575,7 @@ export default class Config {

    let rootSchema = this.schema;
    if (keyPath) {
      for (let key of splitKeyPath(keyPath)) {
      for (const key of splitKeyPath(keyPath)) {
        rootSchema.type = 'object';
        if (rootSchema.properties == null) {
          rootSchema.properties = {};


@@ 650,7 650,7 @@ export default class Config {
  setDefaults(keyPath: string, defaults) {
    if (defaults != null && isPlainObject(defaults)) {
      const keys = splitKeyPath(keyPath);
      for (let key in defaults) {
      for (const key in defaults) {
        const childValue = defaults[key];
        if (!defaults.hasOwnProperty(key)) {
          continue;


@@ 690,7 690,7 @@ export default class Config {
    ) {
      const defaults = {};
      const properties = schema.properties || {};
      for (let key in properties) {
      for (const key in properties) {
        const value = properties[key];
        defaults[key] = this.extractDefaultsFromSchema(value);
      }


@@ 699,7 699,7 @@ export default class Config {
  }

  makeValueConformToSchema(keyPath, value) {
    let schema = this.getSchema(keyPath);
    const schema = this.getSchema(keyPath);
    if (schema) {
      value = Config.executeSchemaEnforcers(keyPath, value, schema);
    }


@@ 839,7 839,7 @@ Config.addSchemaEnforcers({
      }

      const newValue = {};
      for (let prop in value) {
      for (const prop in value) {
        const propValue = value[prop];
        const childSchema = schema.properties[prop];
        if (childSchema != null) {


@@ 872,7 872,7 @@ Config.addSchemaEnforcers({
      const itemSchema = schema.items;
      if (itemSchema != null) {
        const newValue = [];
        for (let item of value) {
        for (const item of value) {
          try {
            newValue.push(this.executeSchemaEnforcers(keyPath, item, itemSchema));
          } catch (error) {


@@ 906,7 906,7 @@ Config.addSchemaEnforcers({
        return value;
      }

      for (let possibleValue of possibleValues) {
      for (const possibleValue of possibleValues) {
        // Using `isEqual` for possibility of placing enums on array and object schemas
        if (_.isEqual(possibleValue, value)) {
          return value;


@@ 945,7 945,7 @@ var splitKeyPath = function(keyPath) {
var withoutEmptyObjects = function(object) {
  let resultObject = undefined;
  if (isPlainObject(object)) {
    for (let key in object) {
    for (const key in object) {
      const value = object[key];
      const newValue = withoutEmptyObjects(value);
      if (newValue != null) {

M app/src/decorators/inflates-draft-client-id.tsx => app/src/decorators/inflates-draft-client-id.tsx +1 -1
@@ 27,7 27,7 @@ function InflatesDraftClientId(

    static containerRequired = false;

    _mounted: boolean = false;
    _mounted = false;
    _sessionUnlisten?: () => void;

    constructor(props) {

M app/src/dom-utils.ts => app/src/dom-utils.ts +1 -1
@@ 28,7 28,7 @@ var DOMUtils = {
    if (node.nodeType === Node.TEXT_NODE) {
      return node;
    }
    for (let childNode of node.childNodes) {
    for (const childNode of node.childNodes) {
      if (childNode.nodeType === Node.TEXT_NODE) {
        return childNode;
      } else if (childNode.nodeType === Node.ELEMENT_NODE) {

M app/src/flux/models/utils.ts => app/src/flux/models/utils.ts +6 -6
@@ 79,7 79,7 @@ export function convertToModel(json) {

export function fastOmit(props, without) {
  const otherProps = Object.assign({}, props);
  for (let w of without) {
  for (const w of without) {
    delete otherProps[w];
  }
  return otherProps;


@@ 94,9 94,9 @@ export function escapeRegExp(str) {
}

export function range(left, right, inclusive = true) {
  let range = [];
  let ascending = left < right;
  let end = !inclusive ? right : ascending ? right + 1 : right - 1;
  const range = [];
  const ascending = left < right;
  const end = !inclusive ? right : ascending ? right + 1 : right - 1;
  for (let i = left; ascending ? i < end : i > end; ascending ? i++ : i--) {
    range.push(i);
  }


@@ 145,7 145,7 @@ export function deepClone(object, customizer?, stackSeen = [], stackRefs = []) {

  // It's important to use getOwnPropertyNames instead of Object.keys to
  // get the non-enumerable items as well.
  for (let key of Object.getOwnPropertyNames(object)) {
  for (const key of Object.getOwnPropertyNames(object)) {
    const newVal = deepClone(object[key], customizer, stackSeen, stackRefs);
    if (_.isFunction(customizer)) {
      newObject[key] = customizer(key, newVal);


@@ 158,7 158,7 @@ export function deepClone(object, customizer?, stackSeen = [], stackRefs = []) {

export function toSet(arr = []) {
  const set = {};
  for (let item of arr) {
  for (const item of arr) {
    set[item] = true;
  }
  return set;

M app/src/flux/stores/contact-store.ts => app/src/flux/stores/contact-store.ts +1 -1
@@ 80,7 80,7 @@ class ContactStore extends MailspringStore {
      .where(Contact.attributes.hidden.equal(false))
      .order(Contact.attributes.refs.descending())
      .then(async _results => {
        let results = this._distinctByEmail(this._omitFindInMailDisabled(_results));
        const results = this._distinctByEmail(this._omitFindInMailDisabled(_results));
        if (results.length > limit) {
          results.length = limit;
        }

M app/src/flux/stores/database-store.ts => app/src/flux/stores/database-store.ts +1 -1
@@ 217,7 217,7 @@ class DatabaseStore extends MailspringStore {
  //
  // If a query is made before the database has been opened, the query will be
  // held in a queue and run / resolved when the database is ready.
  _query(query: SQLString, values: SQLValue[] = [], background: boolean = false) {
  _query(query: SQLString, values: SQLValue[] = [], background = false) {
    return new Promise(async (resolve, reject) => {
      if (!this._open) {
        this._waiting.push(() => this._query(query, values).then(resolve, reject));

M app/src/flux/stores/draft-editing-session.ts => app/src/flux/stores/draft-editing-session.ts +1 -1
@@ 180,7 180,7 @@ export class DraftEditingSession extends MailspringStore {

  _draft: MessageWithEditorState = null;
  _draftPromise: Promise<Message> = null;
  _destroyed: boolean = false;
  _destroyed = false;
  _mountedEditor: Editor | null = null;

  headerMessageId: string;

M app/src/flux/stores/feature-usage-store.tsx => app/src/flux/stores/feature-usage-store.tsx +1 -1
@@ 82,7 82,7 @@ class FeatureUsageStore extends MailspringStore {
    } else {
      headerText = headerText || localized("You've reached your quota");

      let time = featureData.period === 'monthly' ? localized('month') : localized('week');
      const time = featureData.period === 'monthly' ? localized('month') : localized('week');
      rechargeText = rechargeText.replace('%1$@', featureData.quota).replace('%2$@', time);
    }


M app/src/flux/stores/message-store.ts => app/src/flux/stores/message-store.ts +3 -3
@@ 16,7 16,7 @@ const FolderNamesHiddenByDefault = ['spam', 'trash'];
class _MessageStore extends MailspringStore {
  FolderNamesHiddenByDefault = FolderNamesHiddenByDefault;

  _showingHiddenItems: boolean = false;
  _showingHiddenItems = false;
  _items?: Message[];
  _thread?: Thread;
  _itemsExpanded: { [messageId: string]: 'explicit' | 'default' };


@@ 200,7 200,7 @@ class _MessageStore extends MailspringStore {
  }

  _setWindowTitle() {
    let title = 'Mailspring' + (this._thread ? ' · ' + this._thread.subject : '');
    const title = 'Mailspring' + (this._thread ? ' · ' + this._thread.subject : '');
    electron.remote.getCurrentWindow().setTitle(title);
  }



@@ 318,7 318,7 @@ class _MessageStore extends MailspringStore {
  }

  _fetchExpandedAttachments(items) {
    for (let item of items) {
    for (const item of items) {
      if (!this._itemsExpanded[item.id]) continue;
      item.files.map(file => Actions.fetchFile(file));
    }

M app/src/flux/stores/workspace-store.ts => app/src/flux/stores/workspace-store.ts +1 -1
@@ 296,7 296,7 @@ class WorkspaceStore extends MailspringStore {
  defineSheet(id, options: Partial<SheetDeclaration> = {}, columns = {}) {
    // Make sure all the locations have definitions so that packages
    // can register things into these locations and their toolbars.
    for (let layout in columns) {
    for (const layout in columns) {
      const cols = columns[layout];
      for (let idx = 0; idx < cols.length; idx++) {
        const col = cols[idx];

M app/src/intl.ts => app/src/intl.ts +1 -1
@@ 236,7 236,7 @@ export function localizedReactFragment(en, ...subs) {
  // Support "%@ and %@" OR "%1$@ and %2$@" which allows for param reordering.
  // The translation may contain this format even if the original string does not.

  let parts = [];
  const parts = [];
  let match = null;
  let used = 0;
  while ((match = /%(?:(\d)+\$)?@/g.exec(translated))) {

M app/src/keymap-manager.ts => app/src/keymap-manager.ts +1 -1
@@ 107,7 107,7 @@ export default class KeymapManager {
  _removeTemplate?: Disposable;
  _bindingsCache: {};
  _commandsCache: {};
  _altKeyDown: boolean = false;
  _altKeyDown = false;
  _altKeyTimer: NodeJS.Timeout = null;

  EVENT_ALT_KEY_STATE_CHANGE = 'alt-key-state-change';

M app/src/linux-theme-utils.ts => app/src/linux-theme-utils.ts +2 -2
@@ 224,7 224,7 @@ function getIconFromTheme(
  scale: 1 | 2 = 1
) {
  const icons = __getAllIconPaths(theme, iconName, size, contexts, scale);
  for (let path of icons) {
  for (const path of icons) {
    if (fs.existsSync(path)) {
      return fs.realpathSync(path);
    }


@@ 258,7 258,7 @@ function getIconPath(iconName: string, size: number, context: string | string[],
  }

  // in case the icon was not found in the theme, we search the inherited themes
  for (let key of inherits) {
  for (const key of inherits) {
    const inheritsTheme = getIconTheme(inherits[key]);
    if (!inheritsTheme) continue;
    icon = getIconFromTheme(inheritsTheme, iconName, size, context);

M app/src/mailbox-perspective.ts => app/src/mailbox-perspective.ts +1 -1
@@ 530,7 530,7 @@ class CategoryMailboxPerspective extends MailboxPerspective {
  // - if finished category === "archive" remove the label
  // - if finished category === "trash" move to trash folder, keep labels intact
  //
  tasksForRemovingItems(threads, source: string = 'Removed from list') {
  tasksForRemovingItems(threads, source = 'Removed from list') {
    ChangeLabelsTask =
      ChangeLabelsTask || require('./flux/tasks/change-labels-task').ChangeLabelsTask;
    ChangeFolderTask =

M app/src/mailsync-process.ts => app/src/mailsync-process.ts +1 -1
@@ 156,7 156,7 @@ export class MailsyncProcess extends EventEmitter {
    // attached yet, but will be by the caller of spawnProcess.
    if (this.account && this._proc.stdout) {
      this._proc.stdout.once('data', () => {
        var rs = new Readable();
        const rs = new Readable();
        rs.push(`${JSON.stringify(this.account)}\n${JSON.stringify(this.identity)}\n`);
        rs.push(null);
        rs.pipe(

M app/src/menu-helpers.ts => app/src/menu-helpers.ts +2 -2
@@ 58,7 58,7 @@ export function unmerge(menu: IMenuItem[], item: IMenuItem) {

  if (matchingItem != null) {
    if (item.submenu != null) {
      for (let submenuItem of Array.from(item.submenu)) {
      for (const submenuItem of Array.from(item.submenu)) {
        unmerge(matchingItem.submenu, submenuItem);
      }
    }


@@ 110,7 110,7 @@ export function cloneMenuItem(item: IMenuItem) {

export function forEachMenuItem(menu: IMenuItem[], callback: (item: IMenuItem) => void) {
  const result = [];
  for (let item of Array.from(menu)) {
  for (const item of Array.from(menu)) {
    if (item.submenu != null) {
      forEachMenuItem(item.submenu, callback);
    }

M app/src/quickpreview/index.ts => app/src/quickpreview/index.ts +1 -1
@@ 5,7 5,7 @@ import { File } from 'mailspring-exports';

let quickPreviewWindow = null;
let captureWindow = null;
let captureQueue = [];
const captureQueue = [];

const FileSizeLimit = 5 * 1024 * 1024;
const ThumbnailWidth = 320 * (11 / 8.5);

M app/src/registries/command-registry.ts => app/src/registries/command-registry.ts +1 -1
@@ 6,7 6,7 @@ export default class CommandRegistry {
  emitter = new Emitter();
  listenerCounts = {};
  listenerCountChanges = {};
  pendingEmit: boolean = false;
  pendingEmit = false;

  add(
    target: Element,

M app/src/registries/component-registry.ts => app/src/registries/component-registry.ts +1 -1
@@ 18,7 18,7 @@ class ComponentRegistry extends MailspringStore {
    };
  } = {};
  _cache = {};
  _showComponentRegions: boolean = false;
  _showComponentRegions = false;

  // Public: Register a new component with the Component Registry.
  // Typically, packages call this method from their main `activate` method

M app/src/services/quoted-html-transformer.ts => app/src/services/quoted-html-transformer.ts +1 -1
@@ 423,7 423,7 @@ class QuotedHTMLTransformer {
    // This traverses the DOM, walking up the tree and adding all siblings below
    // our current path to the array.
    let head = headerContainer;
    let results = [];
    const results = [];
    while (head) {
      results.push(head);
      while (head && !head.nextElementSibling) {

M app/src/services/sanitize-transformer.ts => app/src/services/sanitize-transformer.ts +4 -4
@@ 451,7 451,7 @@ class SanitizeTransformer {
  Preset = Preset;

  sanitizeNode(node: Element, settings) {
    let nodeName = node.nodeName.toLowerCase();
    const nodeName = node.nodeName.toLowerCase();
    if (nodeName === '#text') {
      return true; // text nodes are always safe, don't need to clone them
    }


@@ 470,7 470,7 @@ class SanitizeTransformer {

      // Nodes with text contents / no contents: replace with a `span` with the same children.
      // This allows us to ignore things like tables / table cells and still get their contents.
      let replacementNode = document.createElement('span');
      const replacementNode = document.createElement('span');
      for (const child of Array.from(node.childNodes)) {
        replacementNode.appendChild(child);
      }


@@ 517,8 517,8 @@ class SanitizeTransformer {

  async run(body, settings) {
    if (settings.fragment) {
      var doc = document.implementation.createHTMLDocument();
      var div = doc.createElement('div');
      const doc = document.implementation.createHTMLDocument();
      const div = doc.createElement('div');
      div.innerHTML = body;
      this.sanitizeNode(div, settings);
      return div.innerHTML;

M app/src/services/search/search-query-parser.ts => app/src/services/search/search-query-parser.ts +1 -1
@@ 315,7 315,7 @@ const parseOrQuery = (text: string) => {
};

const parseAndQuery = text => {
  let [lhs, afterLhs] = parseOrQuery(text);
  const [lhs, afterLhs] = parseOrQuery(text);
  let [tok, afterTok] = nextToken(afterLhs);
  if (tok === null) {
    return [lhs, afterLhs];

M app/src/sheet-container.tsx => app/src/sheet-container.tsx +1 -1
@@ 61,7 61,7 @@ export default class SheetContainer extends React.Component<{}, SheetContainerSt
    this.setState(this._getStateFromStores());
  };

  _lastToolbarClickTime: number = 0;
  _lastToolbarClickTime = 0;

  _onToolbarDoubleClick = (e: React.MouseEvent<HTMLDivElement>) => {
    if (process.platform !== 'darwin') return;

M app/src/sheet-toolbar.tsx => app/src/sheet-toolbar.tsx +1 -1
@@ 226,7 226,7 @@ export default class Toolbar extends React.Component<ToolbarProps, ToolbarState>
    sheetDepth: PropTypes.number,
  };

  mounted: boolean = false;
  mounted = false;
  unlisteners: Array<() => void> = [];

  constructor(props) {

M app/src/theme-manager.ts => app/src/theme-manager.ts +1 -1
@@ 197,7 197,7 @@ export default class ThemeManager {

  cssContentsOfLessStylesheet(lessStylesheetPath) {
    try {
      let less = fs.readFileSync(lessStylesheetPath, 'utf8').toString();
      const less = fs.readFileSync(lessStylesheetPath, 'utf8').toString();
      return this.lessCache.cssForFile(lessStylesheetPath, less);
    } catch (error) {
      let message = `Error loading Less stylesheet: ${lessStylesheetPath}`;