UNPKG

skynovel

Version:
268 lines 12.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const SysNode_1 = require("./SysNode"); const CmnLib_1 = require("./CmnLib"); const Main_1 = require("./Main"); const { remote, shell, ipcRenderer } = require('electron'); const Store = require('electron-store'); const { Readable } = require('stream'); const m_fs = require("fs-extra"); const crypto = require('crypto'); class SysApp extends SysNode_1.SysNode { constructor(hPlg = {}, arg = { cur: 'prj/', crypto: false, dip: '' }) { super(hPlg, { cur: remote.app.getAppPath().replace(/\\/g, '/') + '/' + arg.cur, crypto: arg.crypto, dip: '' }); this.$path_desktop = remote.app.getPath('desktop').replace(/\\/g, '/') + '/'; this.$path_userdata = remote.app.getPath('userData').replace(/\\/g, '/') + '/'; this.normalize = (src, form) => src.normalize(form); this.store = new Store({ cwd: 'storage', name: this.arg.crypto ? 'data_' : 'data' }); this.isMovingWin = false; this.posMovingWin = [0, 0]; this.dsp = remote.screen.getPrimaryDisplay(); this.win = remote.getCurrentWindow(); this.wc = this.win.webContents; this.close = () => { this.win.close(); return false; }; this.navigate_to = hArg => { const url = hArg.url; if (!url) throw '[navigate_to] urlは必須です'; shell.openExternal(url); return false; }; this.title = hArg => { const text = hArg.text; if (!text) throw '[title] textは必須です'; this.win.setTitle(text); return false; }; this.tgl_full_scr = hArg => { if (!hArg.key) { this.tgl_full_scr_sub(); return false; } const key = hArg.key.toLowerCase(); document.addEventListener('keydown', (e) => { const key2 = (e.altKey ? (e.key == 'Alt' ? '' : 'alt+') : '') + (e.ctrlKey ? (e.key == 'Control' ? '' : 'ctrl+') : '') + (e.shiftKey ? (e.key == 'Shift' ? '' : 'shift+') : '') + e.key.toLowerCase(); if (key2 != key) return; e.stopPropagation(); this.tgl_full_scr_sub(); }, { passive: true }); return false; }; this.tgl_full_scr_sub = () => { if (this.win.isSimpleFullScreen()) { this.win.setSimpleFullScreen(false); this.win.setSize(CmnLib_1.CmnLib.stageW, CmnLib_1.CmnLib.stageH); this.appPixi.view.style.width = CmnLib_1.CmnLib.stageW + 'px'; this.appPixi.view.style.height = CmnLib_1.CmnLib.stageH + 'px'; this.appPixi.view.style.marginLeft = '0px'; this.appPixi.view.style.marginTop = '0px'; this.window({}); this.reso4frame = 1; } else { const w = this.dsp.size.width; const h = this.dsp.size.height; const ratioWidth = w / CmnLib_1.CmnLib.stageW; const ratioHeight = h / CmnLib_1.CmnLib.stageH; const ratio = (ratioWidth < ratioHeight) ? ratioWidth : ratioHeight; this.win.setSize(CmnLib_1.CmnLib.stageW * ratio, CmnLib_1.CmnLib.stageH * ratio); this.appPixi.view.style.width = (CmnLib_1.CmnLib.stageW * ratio) + 'px'; this.appPixi.view.style.height = (CmnLib_1.CmnLib.stageH * ratio) + 'px'; if (ratioWidth < ratioHeight) { this.appPixi.view.style.marginTop = (h - CmnLib_1.CmnLib.stageH * ratio) / 2 + 'px'; } else { this.appPixi.view.style.marginLeft = (w - CmnLib_1.CmnLib.stageW * ratio) / 2 + 'px'; } this.win.setSimpleFullScreen(true); this.win.setContentSize(screen.width, screen.height); const cr = this.appPixi.view.getBoundingClientRect(); this.reso4frame = cr.width / CmnLib_1.CmnLib.stageW; } this.resizeFrames(); }; this.update_check = hArg => { const url = hArg.url; if (!url) throw '[update_check] urlは必須です'; if (url.slice(-1) != '/') throw '[update_check] urlの最後は/です'; (async () => { const res = await this.fetch(url + `latest${CmnLib_1.CmnLib.isMac ? '-mac' : ''}.yml`); if (!res.ok) return; if (CmnLib_1.CmnLib.debugLog) console.log(`[update_check] ymlを取得しました url=${url}`); const txt = await res.text(); const mv = /version: (.+)/.exec(txt); if (!mv) throw `[update_check] ファイル内にversionが見つかりません`; const netver = mv[1]; const myver = remote.app.getVersion(); if (netver == myver) { if (CmnLib_1.CmnLib.debugLog) console.log(`[update_check] バージョン更新なし ver:${myver}`); return; } if (CmnLib_1.CmnLib.debugLog) console.log(`[update_check] 現在ver=${myver} 新規ver=${netver}`); const o = { title: 'アプリ更新', icon: remote.app.getAppPath() + '/app/icon.png', buttons: ['OK', 'Cancel'], defaultId: 0, cancelId: 1, message: `アプリ【${this.cfg.oCfg.book.title}】に更新があります。\nダウンロードしますか?`, detail: `現在ver ${myver}\n新規ver ${netver}`, }; const di = await remote.dialog.showMessageBox(o); if (di.response > 0) return; if (CmnLib_1.CmnLib.debugLog) console.log(`[update_check] アプリダウンロード開始`); const mp = /path: (.+)/.exec(txt); if (!mp) throw `[update_check] ファイル内にpathが見つかりません`; const fn = mp[1]; const mc = /sha512: (.+)/.exec(txt); if (!mc) throw `[update_check] ファイル内にsha512が見つかりません`; const sha = mc[1]; const res_dl = await this.fetch(url + fn); if (!res_dl.ok) return; const pathDL = remote.app.getPath('downloads') + '/' + fn; const rd_dl = (res) => { const reader = res.body.getReader(); const rdb = new Readable(); rdb._read = async () => { const { done, value } = await reader.read(); if (done) { rdb.push(null); return; } rdb.push(Buffer.from(value)); }; return rdb; }; const pipe_dl = await rd_dl(res_dl); pipe_dl.on('end', () => { if (CmnLib_1.CmnLib.debugLog) console.log(`[update_check] アプリダウンロード完了`); m_fs.readFile(pathDL, (err, data) => { if (err) throw err; const h = crypto.createHash('SHA512'); h.update(data); const hash = h.digest('base64'); const isOk = sha == hash; if (CmnLib_1.CmnLib.debugLog) console.log(`[update_check] SHA512 Checksum:${isOk}`, sha, hash); if (!isOk) m_fs.unlink(pathDL); o.buttons.pop(); o.message = `アプリ【${this.cfg.oCfg.book.title}】の更新パッケージを\nダウンロードしました` + (isOk ? '' : 'が、破損しています。\n開発元に連絡してください'); remote.dialog.showMessageBox(o); }); }); pipe_dl.pipe(m_fs.createWriteStream(pathDL)); })(); return false; }; this.window = hArg => { const screenRX = this.dsp.size.width; const screenRY = this.dsp.size.height; if (CmnLib_1.CmnLib.argChk_Boolean(hArg, 'centering', false)) { const s = this.win.getPosition(); hArg.x = (screenRX - s[0]) * 0.5; hArg.y = (screenRY - s[1]) * 0.5; } else { hArg.x = CmnLib_1.CmnLib.argChk_Num(hArg, 'x', Number(this.val.getVal('sys:const.sn.nativeWindow.x', 0))); hArg.y = CmnLib_1.CmnLib.argChk_Num(hArg, 'y', Number(this.val.getVal('sys:const.sn.nativeWindow.y', 0))); if (hArg.x < 0) hArg.x = 0; else if (hArg.x > screenRX) hArg.x = 0; if (hArg.y < 0) hArg.y = 0; else if (hArg.y > screenRY) hArg.y = 0; } this.win.setPosition(hArg.x, hArg.y); this.win.setContentSize(CmnLib_1.CmnLib.stageW, CmnLib_1.CmnLib.stageH); const hz = this.win.getContentSize()[1]; this.win.setContentSize(CmnLib_1.CmnLib.stageW, CmnLib_1.CmnLib.stageH * 2 - hz); this.val.setVal_Nochk('sys', 'const.sn.nativeWindow.x', hArg.x); this.val.setVal_Nochk('sys', 'const.sn.nativeWindow.y', hArg.y); this.flush(); return false; }; window.addEventListener('DOMContentLoaded', () => new Main_1.Main(this), { once: true, passive: true }); ipcRenderer.on('log', (e, arg) => console.log(`[main log] e:%o arg:%o`, e, arg)); } initVal(data, hTmp, comp) { if (this.crypto) this.store.encryptionKey = this.stk(); if (this.store.size == 0) { hTmp['const.sn.isFirstBoot'] = true; this.data.sys = data['sys']; this.data.mark = data['mark']; this.data.kidoku = data['kidoku']; this.flush(); } else { hTmp['const.sn.isFirstBoot'] = false; this.data.sys = this.store.store['sys']; this.data.mark = this.store.store['mark']; this.data.kidoku = this.store.store['kidoku']; } comp(this.data); hTmp['const.sn.isDebugger'] = false; hTmp['const.sn.screenResolutionX'] = this.dsp.size.width; hTmp['const.sn.screenResolutionY'] = this.dsp.size.height; this.val.defTmp('const.sn.displayState', () => this.win.isSimpleFullScreen()); window.addEventListener('resize', () => { this.window((hTmp['const.sn.isFirstBoot']) ? { centering: true } : {}); }, { once: true, passive: true }); this.win.on('move', () => { if (this.isMovingWin) return; this.isMovingWin = true; this.posMovingWin = this.win.getPosition(); setTimeout(() => this.delayWinPos(), 500); }); } delayWinPos() { if (this.win.isSimpleFullScreen()) return; const p = this.win.getPosition(); if (this.posMovingWin[0] != p[0] || this.posMovingWin[1] != p[1]) { this.posMovingWin = p; setTimeout(() => this.delayWinPos(), 500); return; } this.window({ x: p[0], y: p[1] }); this.isMovingWin = false; } flush() { this.store.store = this.data; } init(cfg, hTag, appPixi, val, main) { super.init(cfg, hTag, appPixi, val, main); this.cfg = cfg; if (cfg.oCfg.debug.devtool) this.wc.openDevTools(); else this.wc.on('devtools-opened', () => { console.error(`DevToolは禁止されています。許可する場合は【プロジェクト設定】の【devtool】をONに。`); main.destroy(); }); this.win.setContentSize(CmnLib_1.CmnLib.stageW, CmnLib_1.CmnLib.stageH); } } exports.SysApp = SysApp; //# sourceMappingURL=SysApp.js.map