<repo_name>taq-f/kancollectron<file_sep>/src_main/wiki.js
export const WIKI_URLS = new Map([
  ['expedition', 'https://wikiwiki.jp/kancolle/%E9%81%A0%E5%BE%81'],
  [
    'shipbuilding',
    'https://wikiwiki.jp/kancolle/%E5%BB%BA%E9%80%A0%E3%83%AC%E3%82%B7%E3%83%94',
  ],
  [
    'develop',
    'https://wikiwiki.jp/kancolle/%E9%96%8B%E7%99%BA%E3%83%AC%E3%82%B7%E3%83%94',
  ],
])
<file_sep>/src_main/menu.js
import { Menu } from 'electron'
import { WIKI_URLS } from './wiki'
import {
  alwaysOnTop,
  mute,
  reload,
  screenShot,
  shrink,
  toggleDevTool,
  wiki,
} from './actions'

export default function createMenu() {
  const template = [
    {
      label: 'Debug',
      submenu: [
        {
          accelerator: 'CmdOrCtrl+R',
          click: (_, w) => reload.next(w),
          label: 'Reload',
        },
        {
          accelerator:
            process.platform === 'darwin' ? 'Alt+Command+I' : 'Ctrl+Shift+I',
          click: (_, w) => toggleDevTool.next(w),
          label: 'Toggle Developer Tools',
        },
      ],
    },
    {
      label: 'Tools',
      submenu: [
        {
          accelerator: 'CmdOrCtrl+M',
          checked: false,
          click: (item, w) => mute.next({ w, mute: item.checked }),
          label: 'Mute',
          type: 'checkbox',
        },
        {
          accelerator: 'CmdOrCtrl+S',
          checked: false,
          click: (item, w) => shrink.next({ w, shrink: item.checked }),
          label: 'Shrink',
          type: 'checkbox',
        },
        {
          checked: false,
          click: (item, w) => alwaysOnTop.next({ w, onTop: item.checked }),
          label: 'Always On Top',
          type: 'checkbox',
        },
        {
          accelerator: 'CmdOrCtrl+S',
          click: (_, w) => screenShot.next(w),
          label: 'Screen Shot',
        },
      ],
    },
    {
      label: 'Wiki',
      submenu: [
        {
          click: () => {
            Array.from(WIKI_URLS.keys()).forEach(page => {
              wiki.next(page)
            })
          },
          label: 'すべて',
        },
        {
          click: () => wiki.next('expedition'),
          label: '遠征',
        },
        {
          click: () => wiki.next('shipbuilding'),
          label: '建造レシピ',
        },
        {
          click: () => wiki.next('develop'),
          label: '開発レシピ',
        },
      ],
    },
  ]

  const menu = Menu.buildFromTemplate(template)
  Menu.setApplicationMenu(menu)
}
<file_sep>/src_main/actions.js
import { dialog, shell } from 'electron'
import { writeFile } from 'fs'
import { Subject } from 'rxjs'
import { map } from 'rxjs/operators'
import BROWSER_WINDOW_OPTIONS from './browser-window-option'
import { WIKI_URLS } from './wiki'

/**
 * Toggle browser window state: always on top
 */
export const alwaysOnTop = new Subject()
/**
 * Toggle browser window state: mute
 */
export const mute = new Subject()
/**
 * Reload
 */
export const reload = new Subject()
/**
 * Capture screen
 */
export const screenShot = new Subject()
/**
 * Resize browser window
 */
export const shrink = new Subject()
/**
 * Toggle developer tool
 */
export const toggleDevTool = new Subject()
/**
 * Open wiki page
 */
export const wiki = new Subject()

// *****************************************************************************
// Action Procedures
// *****************************************************************************

reload.subscribe(w => w.reload())

toggleDevTool.subscribe(w => w.webContents.toggleDevTools())

mute.subscribe(param => param.w.webContents.send('mute', param.mute))

shrink
  .pipe(
    map(param => {
      let factor
      if (param.shrink) {
        factor = 0.7
      } else {
        factor = 1
      }
      return {
        factor,
        height: Math.round(BROWSER_WINDOW_OPTIONS.height * factor),
        w: param.w,
        width: Math.round(BROWSER_WINDOW_OPTIONS.width * factor),
      }
    })
  )
  .subscribe(param => {
    param.w.setContentSize(param.width, param.height)
    param.w.webContents.send('resize', param.factor)
  })

alwaysOnTop.subscribe(param => param.w.setAlwaysOnTop(param.onTop))

screenShot.subscribe(async w => {
  const filename = await new Promise(resolve => {
    dialog.showSaveDialog(w, {}, f => {
      resolve(f)
    })
  })

  if (!filename) {
    return
  }

  const nativeImage = await new Promise(resolve => {
    const size = w.getSize()
    w.capturePage({ x: 0, y: 0, width: size[0], height: size[1] }, image => {
      resolve(image)
    })
  })

  const buffer = nativeImage.toPNG()

  try {
    await new Promise((resolve, reject) => {
      writeFile(filename, buffer, err => {
        if (err) {
          reject(err)
        } else {
          resolve(filename)
        }
      })
    })
  } catch (error) {
    dialog.showMessageBox(w, {
      buttons: ['OK'],
      detail: error.message,
      message: 'Failed to capture page',
      title: 'Error!',
      type: 'error',
    })
  }
})

wiki.pipe(map(page => WIKI_URLS.get(page))).subscribe(url => {
  if (url) {
    shell.openExternal(url)
  }
})
<file_sep>/src_main/browser-window-option.js
const BROWSER_WINDOW_OPTIONS = {
  height: 720,
  resizable: false,
  useContentSize: true,
  width: 1200,
}

export default BROWSER_WINDOW_OPTIONS
