• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gitify-app / gitify / 13089087317

01 Feb 2025 01:27PM UTC coverage: 87.327% (-0.04%) from 87.364%
13089087317

Pull #1803

github

web-flow
Merge 03177131f into 2e515d06c
Pull Request #1803: fix(deps): update react-router-dom to v7.1.5

639 of 716 branches covered (89.25%)

Branch coverage included in aggregate %.

1697 of 1959 relevant lines covered (86.63%)

25.09 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/main/main.ts
1
import { app, globalShortcut, ipcMain as ipc, safeStorage } from 'electron';
×
2
import log from 'electron-log';
×
3
import { menubar } from 'menubar';
×
4

5
import { APPLICATION } from '../shared/constants';
×
6
import { namespacedEvent } from '../shared/events';
×
7
import { isMacOS, isWindows } from '../shared/platform';
×
8
import { onFirstRunMaybe } from './first-run';
×
9
import { TrayIcons } from './icons';
×
10
import MenuBuilder from './menu';
×
11
import Updater from './updater';
×
12

13
log.initialize();
×
14

15
const browserWindowOpts = {
×
16
  width: 500,
17
  height: 400,
18
  minWidth: 500,
19
  minHeight: 400,
20
  resizable: false,
21
  skipTaskbar: true, // Hide the app from the Windows taskbar
22
  // TODO ideally we would disable this as use a preload script with a context bridge
23
  webPreferences: {
24
    nodeIntegration: true,
25
    contextIsolation: false,
26
  },
27
};
28

29
const mb = menubar({
×
30
  icon: TrayIcons.idle,
31
  index: `file://${__dirname}/index.html`,
32
  browserWindow: browserWindowOpts,
33
  preloadWindow: true,
34
  showDockIcon: false, // Hide the app from the macOS dock
35
});
36

37
const menuBuilder = new MenuBuilder(mb);
×
38
const contextMenu = menuBuilder.buildMenu();
×
39

40
// Register your app as the handler for a custom protocol
41
const protocol =
42
  process.env.NODE_ENV === 'development' ? 'gitify-dev' : 'gitify';
×
43
app.setAsDefaultProtocolClient(protocol);
×
44

45
if (isMacOS() || isWindows()) {
×
46
  /**
47
   * Electron Auto Updater only supports macOS and Windows
48
   * https://github.com/electron/update-electron-app
49
   */
50
  const updater = new Updater(mb, menuBuilder);
×
51
  updater.initialize();
×
52
}
53

54
let shouldUseAlternateIdleIcon = false;
×
55

56
app.whenReady().then(async () => {
×
57
  await onFirstRunMaybe();
×
58

59
  mb.on('ready', () => {
×
60
    mb.app.setAppUserModelId(APPLICATION.ID);
×
61

62
    // Tray configuration
63
    mb.tray.setToolTip(APPLICATION.NAME);
×
64
    mb.tray.setIgnoreDoubleClickEvents(true);
×
65
    mb.tray.on('right-click', (_event, bounds) => {
×
66
      mb.tray.popUpContextMenu(contextMenu, { x: bounds.x, y: bounds.y });
×
67
    });
68

69
    // Custom key events
70
    mb.window.webContents.on('before-input-event', (event, input) => {
×
71
      if (input.key === 'Escape') {
×
72
        mb.window.hide();
×
73
        event.preventDefault();
×
74
      }
75
    });
76

77
    // DevTools configuration
78
    mb.window.webContents.on('devtools-opened', () => {
×
79
      mb.window.setSize(800, 600);
×
80
      mb.window.center();
×
81
      mb.window.resizable = true;
×
82
      mb.window.setAlwaysOnTop(true);
×
83
    });
84

85
    mb.window.webContents.on('devtools-closed', () => {
×
86
      const trayBounds = mb.tray.getBounds();
×
87
      mb.window.setSize(browserWindowOpts.width, browserWindowOpts.height);
×
88
      mb.positioner.move('trayCenter', trayBounds);
×
89
      mb.window.resizable = false;
×
90
    });
91
  });
92

93
  /**
94
   * Gitify custom IPC events
95
   */
96
  ipc.handle(namespacedEvent('version'), () => app.getVersion());
×
97

98
  ipc.on(namespacedEvent('window-show'), () => mb.showWindow());
×
99

100
  ipc.on(namespacedEvent('window-hide'), () => mb.hideWindow());
×
101

102
  ipc.on(namespacedEvent('quit'), () => mb.app.quit());
×
103

104
  ipc.on(
×
105
    namespacedEvent('use-alternate-idle-icon'),
106
    (_, useAlternateIdleIcon) => {
107
      shouldUseAlternateIdleIcon = useAlternateIdleIcon;
×
108
    },
109
  );
110

111
  ipc.on(namespacedEvent('icon-error'), () => {
×
112
    if (!mb.tray.isDestroyed()) {
×
113
      mb.tray.setImage(TrayIcons.error);
×
114
    }
115
  });
116

117
  ipc.on(namespacedEvent('icon-active'), () => {
×
118
    if (!mb.tray.isDestroyed()) {
×
119
      mb.tray.setImage(
×
120
        menuBuilder.isUpdateAvailable()
×
121
          ? TrayIcons.activeWithUpdate
122
          : TrayIcons.active,
123
      );
124
    }
125
  });
126

127
  ipc.on(namespacedEvent('icon-idle'), () => {
×
128
    if (!mb.tray.isDestroyed()) {
×
129
      if (shouldUseAlternateIdleIcon) {
×
130
        mb.tray.setImage(
×
131
          menuBuilder.isUpdateAvailable()
×
132
            ? TrayIcons.idleAlternateWithUpdate
133
            : TrayIcons.idleAlternate,
134
        );
135
      } else {
136
        mb.tray.setImage(
×
137
          menuBuilder.isUpdateAvailable()
×
138
            ? TrayIcons.idleWithUpdate
139
            : TrayIcons.idle,
140
        );
141
      }
142
    }
143
  });
144

145
  ipc.on(namespacedEvent('update-title'), (_, title) => {
×
146
    if (!mb.tray.isDestroyed()) {
×
147
      mb.tray.setTitle(title);
×
148
    }
149
  });
150

151
  ipc.on(
×
152
    namespacedEvent('update-keyboard-shortcut'),
153
    (_, { enabled, keyboardShortcut }) => {
154
      if (!enabled) {
×
155
        globalShortcut.unregister(keyboardShortcut);
×
156
        return;
×
157
      }
158

159
      globalShortcut.register(keyboardShortcut, () => {
×
160
        if (mb.window.isVisible()) {
×
161
          mb.hideWindow();
×
162
        } else {
163
          mb.showWindow();
×
164
        }
165
      });
166
    },
167
  );
168

169
  ipc.on(namespacedEvent('update-auto-launch'), (_, settings) => {
×
170
    app.setLoginItemSettings(settings);
×
171
  });
172
});
173

174
// Safe Storage
175
ipc.handle(namespacedEvent('safe-storage-encrypt'), (_, settings) => {
×
176
  return safeStorage.encryptString(settings).toString('base64');
×
177
});
178

179
ipc.handle(namespacedEvent('safe-storage-decrypt'), (_, settings) => {
×
180
  return safeStorage.decryptString(Buffer.from(settings, 'base64'));
×
181
});
182

183
// Handle gitify:// custom protocol URL events for OAuth 2.0 callback
184
app.on('open-url', (event, url) => {
×
185
  event.preventDefault();
×
186
  mb.window.webContents.send(namespacedEvent('auth-callback'), url);
×
187
});
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc