commit
c91e5c2197
|
@ -189,6 +189,15 @@ Current log location: {1}`,
|
|||
'settings.beta': 'Opt-in to test unstable prerelease updates',
|
||||
'settings.hwAcceleration': 'Enable hardware acceleration (requires restart)',
|
||||
'settings.bbCodeBar': 'Show BBCode formatting bar',
|
||||
'settings.browserOption': 'Set command for opening clicked links',
|
||||
'settings.browserOptionHeader': 'Browser Settings',
|
||||
'settings.browserOptionTitle': 'Browser Path',
|
||||
'settings.browserOptionPath': 'Path to browser executable',
|
||||
'settings.browserOptionArguments': 'Arguments to pass to executable',
|
||||
'settings.browserOptionArgumentsHelp': 'Arguments are separated by spaces. Use %s to insert the URL.',
|
||||
'settings.browserOptionBrowse': 'Browse',
|
||||
'settings.browserOptionSave': 'Save',
|
||||
'settings.browserOptionReset': 'Reset to default',
|
||||
'fixLogs.action': 'Fix corrupted logs',
|
||||
'fixLogs.text': `There are a few reason log files can become corrupted - log files from old versions with bugs that have since been fixed or incomplete file operations caused by computer crashes are the most common.
|
||||
If one of your log files is corrupted, you may get an "Unknown Type" error when you log in or when you open a specific tab. You may also experience other issues.
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
<template>
|
||||
<div class="card-full" style="display:flex;flex-direction:column;height:100%;" :class="getThemeClass()" @auxclick.prevent>
|
||||
<div v-html="styling"></div>
|
||||
<div style="display:flex;align-items:stretch;border-bottom-width:1px" class="border-bottom" id="window-browser-settings">
|
||||
<h4 style="padding:2px 0">{{l('settings.browserOptionHeader')}}</h4>
|
||||
<div style="flex:1;display:flex;justify-content:flex-end;-webkit-app-region:drag" class="btn-group"
|
||||
id="windowButtons">
|
||||
<i class="far fa-window-minimize btn btn-light" @click.stop="minimize()"></i>
|
||||
<!-- <i class="far btn btn-light" :class="'fa-window-' + (isMaximized ? 'restore' : 'maximize')" @click="maximize()"></i>-->
|
||||
<span class="btn btn-light" @click.stop="close()">
|
||||
<i class="fa fa-times fa-lg"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-light" style="display:flex; flex-direction: column; height:100%; justify-content: center; margin: 0;">
|
||||
<div class="card bg-light" style="height:100%;width:100%;">
|
||||
<div class="card-body row" style="height:100%;width:100%;">
|
||||
<h4 class="card-title">{{l('settings.browserOptionTitle')}}</h4>
|
||||
<div class="form-group col-12">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="warning">
|
||||
<h5>Danger Zone!</h5>
|
||||
<div>This is an advanced setting. By changing this setting to an unsupported program (i.e. not a browser), you might not be able to open links from F-Chat anymore.</div>
|
||||
|
||||
<div v-if="isMac"><hr/>
|
||||
<p>Mac User: As of writing, MacOS has a bug in how it handles opening links.</p>
|
||||
<p>When your default browser is something other than Safari and you select Safari in this settings window, links might be opened twice.</p>
|
||||
<p>Once in Safari and a second time in your default browser. This tends to happen when Safari is not running when clicking a link.</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<label class="control-label" for="browserPath">{{l('settings.browserOptionPath')}}</label>
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<input class="form-control" id="browserPath" v-model="browserPath"/>
|
||||
</div>
|
||||
<div class="col-2">
|
||||
<button class="btn btn-primary" @click.prevent.stop="browseForPath()">{{l('settings.browserOptionBrowse')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<label class="control-label" for="browserArgs">{{l('settings.browserOptionArguments')}}</label>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<input class="form-control" id="browserArgs" v-model="browserArgs"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<small class="form-text text-muted">{{l('settings.browserOptionArgumentsHelp')}}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group col-12">
|
||||
<div class="row no-gutters">
|
||||
<div class="col-2">
|
||||
<button class="btn btn-primary" @click.prevent.stop="submit()">{{l('settings.browserOptionSave')}}</button>
|
||||
</div>
|
||||
<div class="col"></div>
|
||||
<div class="col-4">
|
||||
<button class="btn btn-danger" style="float: right;" @click.prevent.stop="resetToDefault()">{{l('settings.browserOptionReset')}}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import * as electron from 'electron';
|
||||
import {Component, Hook} from '@f-list/vue-ts';
|
||||
import * as remote from '@electron/remote';
|
||||
import Vue from 'vue';
|
||||
import l from '../chat/localize';
|
||||
import {GeneralSettings} from './common';
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import Modal from "../components/Modal.vue";
|
||||
import modal from "../components/Modal.vue";
|
||||
import tabs from "../components/tabs";
|
||||
import logs from "../chat/Logs.vue";
|
||||
import chat from "../chat/ChatView.vue";
|
||||
import {ipcRenderer} from "electron";
|
||||
import {EIconStore} from "../learn/eicon/store";
|
||||
import log from "electron-log";
|
||||
|
||||
const browserWindow = remote.getCurrentWindow();
|
||||
@Component({
|
||||
components: {chat, logs, modal, tabs, Modal}
|
||||
})
|
||||
export default class BrowserOption extends Vue {
|
||||
settings!: GeneralSettings;
|
||||
isMaximized = false;
|
||||
l = l;
|
||||
platform = process.platform;
|
||||
hasCompletedUpgrades = false;
|
||||
browserPath = '';
|
||||
browserArgs = '';
|
||||
isMac = process.platform === 'darwin';
|
||||
|
||||
get styling(): string {
|
||||
try {
|
||||
return `<style>${fs.readFileSync(path.join(__dirname, `themes/${this.settings.theme}.css`), 'utf8').toString()}</style>`;
|
||||
} catch (e) {
|
||||
if ((<Error & { code: string }>e).code === 'ENOENT' && this.settings.theme !== 'default') {
|
||||
this.settings.theme = 'default';
|
||||
return this.styling;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@Hook('mounted')
|
||||
async mounted(): Promise<void> {
|
||||
this.browserPath = this.settings.browserPath;
|
||||
this.browserArgs = this.settings.browserArgs;
|
||||
}
|
||||
|
||||
minimize(): void {
|
||||
browserWindow.minimize();
|
||||
}
|
||||
|
||||
maximize(): void {
|
||||
if (browserWindow.isMaximized()) browserWindow.unmaximize();
|
||||
else browserWindow.maximize();
|
||||
}
|
||||
|
||||
close(): void {
|
||||
browserWindow.close();
|
||||
}
|
||||
|
||||
getThemeClass() {
|
||||
// console.log('getThemeClassWindow', this.settings?.risingDisableWindowsHighContrast);
|
||||
|
||||
try {
|
||||
// Hack!
|
||||
if (process.platform === 'win32') {
|
||||
if (this.settings?.risingDisableWindowsHighContrast) {
|
||||
document.querySelector('html')?.classList.add('disableWindowsHighContrast');
|
||||
} else {
|
||||
document.querySelector('html')?.classList.remove('disableWindowsHighContrast');
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
['platform-' + this.platform]: true,
|
||||
disableWindowsHighContrast: this.settings?.risingDisableWindowsHighContrast || false
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
['platform-' + this.platform]: true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
submit(): void {
|
||||
ipcRenderer.send('browser-option-update', this.browserPath, this.browserArgs);
|
||||
this.close();
|
||||
}
|
||||
|
||||
resetToDefault(): void {
|
||||
this.browserPath = '';
|
||||
this.browserArgs = '';
|
||||
}
|
||||
|
||||
browseForPath(): void {
|
||||
ipcRenderer.invoke('browser-option-browse').then((result) => {
|
||||
this.browserPath = result;
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.card-full {
|
||||
height: 100%;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
#windowButtons .btn {
|
||||
border-top: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
#window-browser-settings {
|
||||
user-select: none;
|
||||
.btn {
|
||||
border: 0;
|
||||
border-radius: 0;
|
||||
padding: 0 18px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 1;
|
||||
-webkit-app-region: no-drag;
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.btn-default {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 0 10px;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
align-self: center;
|
||||
-webkit-app-region: drag;
|
||||
}
|
||||
|
||||
.fa {
|
||||
line-height: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.warning {
|
||||
border: 1px solid var(--warning);
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 3px;
|
||||
|
||||
div {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.disableWindowsHighContrast, .disableWindowsHighContrast * {
|
||||
forced-color-adjust: none;
|
||||
}
|
||||
</style>
|
|
@ -496,7 +496,8 @@
|
|||
}
|
||||
|
||||
async openProfileInBrowser(): Promise<void> {
|
||||
await remote.shell.openExternal(`https://www.f-list.net/c/${this.profileName}`);
|
||||
electron.ipcRenderer.send('open-url-externally', `https://www.f-list.net/c/${this.profileName}`);
|
||||
//await remote.shell.openExternal(`https://www.f-list.net/c/${this.profileName}`);
|
||||
|
||||
// tslint:disable-next-line: no-any no-unsafe-any
|
||||
(this.$refs.profileViewer as any).hide();
|
||||
|
@ -628,7 +629,8 @@
|
|||
|
||||
|
||||
async openWordDefinitionInBrowser(): Promise<void> {
|
||||
await remote.shell.openExternal((this.$refs.wordDefinitionLookup as any).getWebUrl());
|
||||
electron.ipcRenderer.send('open-url-externally', (this.$refs.wordDefinitionLookup as any).getWebUrl());
|
||||
//await remote.shell.openExternal((this.$refs.wordDefinitionLookup as any).getWebUrl());
|
||||
|
||||
// tslint:disable-next-line: no-any no-unsafe-any
|
||||
(this.$refs.wordDefinitionViewer as any).hide();
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline'; img-src https://static.f-list.net">
|
||||
<title>F-Chat</title>
|
||||
<link href="fa.css" rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<div id="browserOption"></div>
|
||||
<script type="text/javascript" src="common.js"></script>
|
||||
<script type="text/javascript" src="browser_option.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,25 @@
|
|||
import * as qs from 'querystring';
|
||||
import log from 'electron-log'; //tslint:disable-line:match-default-export-name
|
||||
|
||||
import {GeneralSettings} from './common';
|
||||
import BrowserOption from './BrowserOption.vue';
|
||||
|
||||
log.info('init.browser_option');
|
||||
|
||||
const params = <{[key: string]: string | undefined}>qs.parse(window.location.search.substr(1));
|
||||
const settings = <GeneralSettings>JSON.parse(params['settings']!);
|
||||
|
||||
const logLevel = (process.env.NODE_ENV === 'production') ? 'info' : 'silly';
|
||||
|
||||
log.transports.file.level = settings.risingSystemLogLevel || logLevel;
|
||||
log.transports.console.level = settings.risingSystemLogLevel || logLevel;
|
||||
log.transports.file.maxSize = 5 * 1024 * 1024;
|
||||
|
||||
log.info('init.browser_option.vue');
|
||||
|
||||
new BrowserOption({
|
||||
el: '#browserOption',
|
||||
data: {settings}
|
||||
});
|
||||
|
||||
log.debug('init.browser_option.vue.done');
|
|
@ -31,6 +31,8 @@ export class GeneralSettings {
|
|||
risingCacheExpiryDays = 30;
|
||||
risingSystemLogLevel: log.LevelOption = 'info';
|
||||
risingDisableWindowsHighContrast = false;
|
||||
browserPath = '';
|
||||
browserArgs = '%s';
|
||||
}
|
||||
|
||||
// //tslint:disable
|
||||
|
|
157
electron/main.ts
157
electron/main.ts
|
@ -53,6 +53,7 @@ import DownloadItem = electron.DownloadItem;
|
|||
import { AdCoordinatorHost } from '../chat/ads/ad-coordinator-host';
|
||||
import { IpcMainEvent } from 'electron';
|
||||
import { BlockerIntegration } from './blocker/blocker';
|
||||
import core from "../chat/core";
|
||||
|
||||
//tslint:disable-next-line:no-require-imports
|
||||
const pck = require('./package.json');
|
||||
|
@ -171,14 +172,70 @@ async function addSpellcheckerItems(menu: electron.Menu): Promise<void> {
|
|||
}));
|
||||
}
|
||||
|
||||
function openURLExternally(linkUrl: string): void {
|
||||
|
||||
// check if user set a path and whether it exists
|
||||
const pathIsValid = (settings.browserPath !== '' && fs.existsSync(settings.browserPath));
|
||||
|
||||
if(pathIsValid) {
|
||||
// also check if the user can execute whatever is located at the selected path
|
||||
let fileIsExecutable = false;
|
||||
try {
|
||||
fs.accessSync(settings.browserPath, fs.constants.X_OK);
|
||||
fileIsExecutable = true;
|
||||
} catch (err) {
|
||||
log.error(`Selected browser is not executable by user. Path: "${settings.browserPath}"`);
|
||||
}
|
||||
|
||||
if (fileIsExecutable) {
|
||||
// check if URL is already encoded
|
||||
// (this should work almost all the time, but there might be edge-cases with very unusual URLs)
|
||||
let isEncoded = (linkUrl !== decodeURI(linkUrl));
|
||||
// only encode URL if it isn't encoded yet
|
||||
if (!isEncoded) {
|
||||
// encode URL so if it contains spaces, it remains a single argument for the browser
|
||||
linkUrl = encodeURI(linkUrl);
|
||||
}
|
||||
|
||||
if (!settings.browserArgs.includes('%s')) {
|
||||
// append %s to params if it is not already there
|
||||
settings.browserArgs += ' %s';
|
||||
}
|
||||
|
||||
// replace %s in arguments with URL and encapsulate in quotes to prevent issues with spaces and special characters in the path
|
||||
let link = settings.browserArgs.replace('%s', '\"' + linkUrl + '\"');
|
||||
|
||||
const execFile = require('child_process').exec;
|
||||
if (process.platform === "darwin") {
|
||||
// NOTE: This is seemingly bugged on MacOS when setting Safari as the external browser while using a different default browser.
|
||||
// In that case, this will open the URL in both the selected application AND the default browser.
|
||||
// Other browsers work fine. (Tested with Chrome with Firefox as the default browser.)
|
||||
// https://developer.apple.com/forums/thread/685385
|
||||
execFile(`open -a "${settings.browserPath}" ${link}`);
|
||||
} else {
|
||||
execFile(`"${settings.browserPath}" ${link}`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
electron.shell.openExternal(linkUrl);
|
||||
}
|
||||
|
||||
function setUpWebContents(webContents: electron.WebContents): void {
|
||||
remoteMain.enable(webContents);
|
||||
|
||||
const openLinkExternally = (e: Event, linkUrl: string) => {
|
||||
e.preventDefault();
|
||||
const profileMatch = linkUrl.match(/^https?:\/\/(www\.)?f-list.net\/c\/([^/#]+)\/?#?/);
|
||||
if(profileMatch !== null && settings.profileViewer) webContents.send('open-profile', decodeURIComponent(profileMatch[2]));
|
||||
else return electron.shell.openExternal(linkUrl);
|
||||
if(profileMatch !== null && settings.profileViewer) {
|
||||
webContents.send('open-profile', decodeURIComponent(profileMatch[2]));
|
||||
return;
|
||||
}
|
||||
|
||||
// otherwise, try to open externally
|
||||
openURLExternally(linkUrl);
|
||||
|
||||
};
|
||||
|
||||
webContents.setVisualZoomLevelLimits(1, 5);
|
||||
|
@ -281,7 +338,44 @@ function createWindow(): electron.BrowserWindow | undefined {
|
|||
|
||||
function showPatchNotes(): void {
|
||||
//tslint:disable-next-line: no-floating-promises
|
||||
electron.shell.openExternal('https://github.com/hearmeneigh/fchat-rising/blob/master/CHANGELOG.md');
|
||||
openURLExternally('https://github.com/hearmeneigh/fchat-rising/blob/master/CHANGELOG.md');
|
||||
}
|
||||
|
||||
function openBrowserSettings(): electron.BrowserWindow | undefined {
|
||||
let desiredHeight = 520;
|
||||
if(process.platform === 'darwin') {
|
||||
desiredHeight = 750;
|
||||
}
|
||||
|
||||
const windowProperties: electron.BrowserWindowConstructorOptions = {
|
||||
center: true,
|
||||
show: false,
|
||||
icon: process.platform === 'win32' ? winIcon : pngIcon,
|
||||
frame: false,
|
||||
width: 650,
|
||||
height: desiredHeight,
|
||||
minWidth: 650,
|
||||
minHeight: desiredHeight,
|
||||
maxWidth: 650,
|
||||
maxHeight: desiredHeight,
|
||||
maximizable: false,
|
||||
webPreferences: {
|
||||
webviewTag: true, nodeIntegration: true, nodeIntegrationInWorker: true, spellcheck: true,
|
||||
enableRemoteModule: true, contextIsolation: false, partition: 'persist:fchat'
|
||||
} as any
|
||||
};
|
||||
|
||||
const browserWindow = new electron.BrowserWindow(windowProperties);
|
||||
remoteMain.enable(browserWindow.webContents);
|
||||
browserWindow.loadFile(path.join(__dirname, 'browser_option.html'), {
|
||||
query: { settings: JSON.stringify(settings), import: shouldImportSettings ? 'true' : '' }
|
||||
});
|
||||
|
||||
browserWindow.once('ready-to-show', () => {
|
||||
browserWindow.show();
|
||||
});
|
||||
|
||||
return browserWindow;
|
||||
}
|
||||
|
||||
|
||||
|
@ -529,6 +623,12 @@ function onReady(): void {
|
|||
settings.risingDisableWindowsHighContrast = item.checked;
|
||||
setGeneralSettings(settings);
|
||||
}
|
||||
},
|
||||
{
|
||||
label: l('settings.browserOption'),
|
||||
click: () => {
|
||||
openBrowserSettings();
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -576,23 +676,23 @@ function onReady(): void {
|
|||
submenu: [
|
||||
{
|
||||
label: l('help.fchat'),
|
||||
click: () => electron.shell.openExternal('https://github.com/hearmeneigh/fchat-rising/blob/master/README.md')
|
||||
click: () => openURLExternally('https://github.com/hearmeneigh/fchat-rising/blob/master/README.md')
|
||||
},
|
||||
// {
|
||||
// label: l('help.feedback'),
|
||||
// click: () => electron.shell.openExternal('https://goo.gl/forms/WnLt3Qm3TPt64jQt2')
|
||||
// click: () => openURLExternally('https://goo.gl/forms/WnLt3Qm3TPt64jQt2')
|
||||
// },
|
||||
{
|
||||
label: l('help.rules'),
|
||||
click: () => electron.shell.openExternal('https://wiki.f-list.net/Rules')
|
||||
click: () => openURLExternally('https://wiki.f-list.net/Rules')
|
||||
},
|
||||
{
|
||||
label: l('help.faq'),
|
||||
click: () => electron.shell.openExternal('https://wiki.f-list.net/Frequently_Asked_Questions')
|
||||
click: () => openURLExternally('https://wiki.f-list.net/Frequently_Asked_Questions')
|
||||
},
|
||||
{
|
||||
label: l('help.report'),
|
||||
click: () => electron.shell.openExternal('https://wiki.f-list.net/How_to_Report_a_User#In_chat')
|
||||
click: () => openURLExternally('https://wiki.f-list.net/How_to_Report_a_User#In_chat')
|
||||
},
|
||||
{label: l('version', app.getVersion()), click: showPatchNotes}
|
||||
]
|
||||
|
@ -665,6 +765,47 @@ function onReady(): void {
|
|||
for(const w of electron.webContents.getAllWebContents()) w.send('update-zoom', zl);
|
||||
});
|
||||
|
||||
electron.ipcMain.handle('browser-option-browse', async () => {
|
||||
log.debug('settings.browserOption.browse');
|
||||
console.log('settings.browserOption.browse', JSON.stringify(settings));
|
||||
|
||||
let filters;
|
||||
if(process.platform === "win32") {
|
||||
filters = [{ name: 'Executables', extensions: ['exe'] }];
|
||||
} else if (process.platform === "darwin") {
|
||||
filters = [{ name: 'Executables', extensions: ['app'] }];
|
||||
} else {
|
||||
// linux and anything else that might be supported
|
||||
// no specific extension for executables
|
||||
filters = [{ name: 'Executables', extensions: ['*'] }];
|
||||
}
|
||||
|
||||
const dir = electron.dialog.showOpenDialogSync(
|
||||
{
|
||||
defaultPath: settings.browserPath,
|
||||
properties: ['openFile'],
|
||||
filters: filters
|
||||
});
|
||||
if(dir !== undefined) {
|
||||
return dir[0];
|
||||
}
|
||||
|
||||
// we keep the current path if the user cancels the dialog
|
||||
return settings.browserPath;
|
||||
});
|
||||
|
||||
electron.ipcMain.on('browser-option-update', (_e, _path: string, _args: string) => {
|
||||
log.debug('Browser Path settings update:', _path, _args);
|
||||
// store the new path and args in our general settings
|
||||
settings.browserPath = _path;
|
||||
settings.browserArgs = _args;
|
||||
setGeneralSettings(settings);
|
||||
});
|
||||
|
||||
electron.ipcMain.on('open-url-externally', (_e, _url: string) => {
|
||||
openURLExternally(_url);
|
||||
});
|
||||
|
||||
createWindow();
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ const mainConfig = {
|
|||
}, rendererConfig = {
|
||||
entry: {
|
||||
chat: [path.join(__dirname, 'chat.ts'), path.join(__dirname, 'index.html')],
|
||||
window: [path.join(__dirname, 'window.ts'), path.join(__dirname, 'window.html'), path.join(__dirname, 'build', 'tray@2x.png')]
|
||||
window: [path.join(__dirname, 'window.ts'), path.join(__dirname, 'window.html'), path.join(__dirname, 'build', 'tray@2x.png')],
|
||||
browser_option: [path.join(__dirname, 'browser_option.ts'), path.join(__dirname, 'browser_option.html'), path.join(__dirname, 'build', 'tray@2x.png')]
|
||||
},
|
||||
output: {
|
||||
path: __dirname + '/app',
|
||||
|
|
Loading…
Reference in New Issue