mirror of
https://github.com/mgerb/ps-launcher
synced 2026-01-09 01:52:57 +00:00
lots of progress - basic functionality work - bundling working
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,4 +1,5 @@
|
|||||||
.vscode
|
.vscode
|
||||||
node_modules
|
node_modules
|
||||||
yarn-error*
|
yarn-error*
|
||||||
dist
|
dist
|
||||||
|
build
|
||||||
|
|||||||
2
@types/all/index.d.ts
vendored
2
@types/all/index.d.ts
vendored
@@ -1 +1 @@
|
|||||||
declare module 'this-is-a-test-module';
|
declare module '*.png';
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# Work in progress
|
# Work in progress
|
||||||
|
|
||||||
## Early Prototype 10/17/2017
|
## Prototype 2 10/18/2017
|
||||||
|

|
||||||
|
|
||||||

|
## Early Prototype 10/17/2017
|
||||||
|

|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
@import '../scss/variables.scss';
|
||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -1,26 +1,33 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Provider } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import AppState from '../state/AppState';
|
import { AppState } from '../state/AppState';
|
||||||
import { Content, Header, ServerList, SubHeader } from '../components';
|
import { Content, Header, ServerList, SubHeader } from '../components';
|
||||||
|
|
||||||
import './Wrapper.scss';
|
import './Wrapper.scss';
|
||||||
|
|
||||||
const stores = { AppState };
|
interface Props {
|
||||||
|
AppState?: AppState;
|
||||||
|
}
|
||||||
|
|
||||||
export class Wrapper extends React.Component<any, any> {
|
@inject('AppState')
|
||||||
|
@observer
|
||||||
|
export class Wrapper extends React.Component<Props, any> {
|
||||||
|
|
||||||
public render(): any {
|
private renderMain(): any {
|
||||||
return (
|
return (
|
||||||
<Provider {...stores}>
|
<div className="wrapper">
|
||||||
<div className="wrapper">
|
<Header />
|
||||||
<Header />
|
<SubHeader />
|
||||||
<SubHeader />
|
<div style={{ display: 'flex', flex: 1 }}>
|
||||||
<div style={{ display: 'flex', flex: 1 }}>
|
<ServerList />
|
||||||
<ServerList />
|
<Content />
|
||||||
<Content />
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</Provider>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public render(): any {
|
||||||
|
// make sure app is bootstrapped before rendering
|
||||||
|
return this.props.AppState.isBootstrapped ? this.renderMain() : <div />;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
app/app.tsx
16
app/app.tsx
@@ -1,9 +1,23 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import { Provider } from 'mobx-react';
|
||||||
|
import AppState from './state/AppState';
|
||||||
import { Wrapper } from './Wrapper/Wrapper';
|
import { Wrapper } from './Wrapper/Wrapper';
|
||||||
import 'babel-polyfill';
|
import 'babel-polyfill';
|
||||||
|
|
||||||
// base styling
|
// base styling
|
||||||
import './scss/index.scss';
|
import './scss/index.scss';
|
||||||
|
|
||||||
ReactDOM.render(<Wrapper />, document.getElementById('app'));
|
const stores = { AppState };
|
||||||
|
|
||||||
|
class App extends React.Component<any, any> {
|
||||||
|
public render(): any {
|
||||||
|
return (
|
||||||
|
<Provider {...stores}>
|
||||||
|
<Wrapper />
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReactDOM.render(<App />, document.getElementById('app'));
|
||||||
|
|||||||
BIN
app/assets/bc.png
Normal file
BIN
app/assets/bc.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 173 KiB |
BIN
app/assets/vanilla.png
Normal file
BIN
app/assets/vanilla.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 240 KiB |
BIN
app/assets/wotlk.png
Normal file
BIN
app/assets/wotlk.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
@@ -13,7 +13,7 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: $blue;
|
background: $blue;
|
||||||
transition: background 0.2s;
|
transition: background 0.2s linear;
|
||||||
outline: none;
|
outline: none;
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
// import fs from 'fs';
|
|
||||||
// import { exec } from 'child_process';
|
|
||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { AppState } from '../../state/AppState';
|
import { AppState } from '../../state/AppState';
|
||||||
@@ -21,29 +19,6 @@ export class Content extends React.Component<Props, any> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// private async startGame(): Promise<void> {
|
|
||||||
// const { path } = this.state;
|
|
||||||
|
|
||||||
// // set the realm list
|
|
||||||
// await this.setRealmList();
|
|
||||||
|
|
||||||
// // launch wow
|
|
||||||
// exec(`"${path}/WoW.exe"`, (err, output) => {
|
|
||||||
// console.log(err);
|
|
||||||
// console.log(output);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private setRealmList(): Promise<any> {
|
|
||||||
// const { path } = this.state;
|
|
||||||
|
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// fs.writeFile(`${path}/realmlist.wtf`, 'set realmlist logon.elysium-project.org', err => {
|
|
||||||
// err ? reject(err) : resolve();
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
private onFolderSelect(e: React.ChangeEvent<HTMLInputElement>): void {
|
private onFolderSelect(e: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
const path: string = _.get(e, `target.files[0].path`);
|
const path: string = _.get(e, `target.files[0].path`);
|
||||||
|
|
||||||
|
|||||||
@@ -42,3 +42,8 @@
|
|||||||
width: 10px;
|
width: 10px;
|
||||||
border: 2px solid;
|
border: 2px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header__version {
|
||||||
|
color: $blue--lighter;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ interface Props {
|
|||||||
AppState?: AppState;
|
AppState?: AppState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare const VERSION: any;
|
||||||
|
|
||||||
@inject('AppState')
|
@inject('AppState')
|
||||||
@observer
|
@observer
|
||||||
export class Header extends React.Component<Props, any> {
|
export class Header extends React.Component<Props, any> {
|
||||||
@@ -35,6 +37,7 @@ export class Header extends React.Component<Props, any> {
|
|||||||
public render(): any {
|
public render(): any {
|
||||||
return (
|
return (
|
||||||
<div className="header">
|
<div className="header">
|
||||||
|
<div className="header__version">PS Launcher <span style={{ fontSize: '10px' }}>v{VERSION}</span></div>
|
||||||
<div className="header__draggable-region"></div>
|
<div className="header__draggable-region"></div>
|
||||||
<div className="header-icon header-icon--minimize" onClick={this.minimize.bind(this)}/>
|
<div className="header-icon header-icon--minimize" onClick={this.minimize.bind(this)}/>
|
||||||
<div className="header-icon header-icon--maximize" onClick={this.maximize.bind(this)}/>
|
<div className="header-icon header-icon--maximize" onClick={this.maximize.bind(this)}/>
|
||||||
|
|||||||
@@ -1,7 +1,73 @@
|
|||||||
@import '../../scss/variables.scss';
|
@import '../../scss/variables.scss';
|
||||||
|
|
||||||
.server-list {
|
.server-list {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
background: darken($dark-blue, 1%);
|
background: darken($dark-blue, 1%);
|
||||||
width: 200px;
|
min-width: 200px;
|
||||||
border-right: 1px solid $dark-blue--3;
|
border-right: 1px solid $dark-blue--3;
|
||||||
|
|
||||||
|
.server-list-heading {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.fa {
|
||||||
|
cursor: pointer;
|
||||||
|
color: $blue;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $blue--lighter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-container {
|
||||||
|
overflow-y: auto;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item {
|
||||||
|
cursor: pointer;
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
text-align: center;
|
||||||
|
background: darken($dark-blue, 1%);
|
||||||
|
transition: all 0.2s linear;
|
||||||
|
border-right: 4px solid transparent;
|
||||||
|
border-left: 4px solid transparent;
|
||||||
|
|
||||||
|
&:hover, &.selected {
|
||||||
|
background: $dark-blue--1;
|
||||||
|
color: lighten($white, 10%);
|
||||||
|
border-left-color: $blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-button-container {
|
||||||
|
height: 100px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-button {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
background: $blue;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
color: $white;
|
||||||
|
font-size: 30px;
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $blue--lighter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import fs from 'fs';
|
||||||
|
import { exec } from 'child_process';
|
||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import { AppState } from '../../state/AppState';
|
import { AppState } from '../../state/AppState';
|
||||||
|
|
||||||
@@ -11,14 +13,62 @@ interface Props {
|
|||||||
@inject('AppState')
|
@inject('AppState')
|
||||||
@observer
|
@observer
|
||||||
export class ServerList extends React.Component<Props, any> {
|
export class ServerList extends React.Component<Props, any> {
|
||||||
|
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private renderItems(): any {
|
||||||
|
const { AppState } = this.props;
|
||||||
|
return this.props.AppState.selectedExpansion.servers.map((server, index) => {
|
||||||
|
const selected = AppState.selectedExpansion.selectedServerIndex === index ? ' selected' : '';
|
||||||
|
return (
|
||||||
|
<div key={index} className={'list-item' + selected} onClick={() => AppState.setSelectedServerIndex(index)}>
|
||||||
|
{server.name}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async play(): Promise<void> {
|
||||||
|
const { directory } = this.props.AppState.selectedExpansion;
|
||||||
|
|
||||||
|
// set the realm list
|
||||||
|
await this.setRealmList();
|
||||||
|
|
||||||
|
// launch wow
|
||||||
|
exec(`"${directory}/WoW.exe"`, (err, output) => {
|
||||||
|
console.log(err);
|
||||||
|
console.log(output);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private setRealmList(): Promise<any> {
|
||||||
|
const { directory } = this.props.AppState.selectedExpansion;
|
||||||
|
const { realmlist } = this.props.AppState.selectedServer;
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.writeFile(`${directory}/realmlist.wtf`, `set realmlist ${realmlist}`, err => {
|
||||||
|
err ? reject(err) : resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public render(): any {
|
public render(): any {
|
||||||
|
const { selectedServer } = this.props.AppState;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="server-list">Server list</div>
|
<div className="server-list">
|
||||||
|
<div className="server-list-heading">
|
||||||
|
<div>Servers</div>
|
||||||
|
<i className="fa fa-plus"/>
|
||||||
|
</div>
|
||||||
|
<div className="item-container">{this.renderItems()}</div>
|
||||||
|
<div className="start-button-container">
|
||||||
|
<button className="start-button" onClick={() => this.play()} disabled={!selectedServer}>
|
||||||
|
Play
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,11 @@
|
|||||||
border-bottom: 1px solid $dark-blue--3;
|
border-bottom: 1px solid $dark-blue--3;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
overflow: auto;
|
overflow-x: auto;
|
||||||
|
|
||||||
.sub-header__item {
|
.sub-header__item {
|
||||||
width: 100px;
|
min-width: 180px;
|
||||||
|
width: 180px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@@ -17,6 +18,10 @@
|
|||||||
&:hover, &.selected {
|
&:hover, &.selected {
|
||||||
background: $dark-blue--3;
|
background: $dark-blue--3;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.exp-image {
|
||||||
|
width: 90%;
|
||||||
|
height: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,16 @@ import { inject, observer } from 'mobx-react';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { AppState } from '../../state/AppState';
|
import { AppState } from '../../state/AppState';
|
||||||
|
|
||||||
|
import vanilla from '../../assets/vanilla.png';
|
||||||
|
import bc from '../../assets/bc.png';
|
||||||
|
import wotlk from '../../assets/wotlk.png';
|
||||||
|
|
||||||
|
const images: any = {
|
||||||
|
vanilla,
|
||||||
|
bc,
|
||||||
|
wotlk,
|
||||||
|
};
|
||||||
|
|
||||||
import './SubHeader.scss';
|
import './SubHeader.scss';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -26,10 +36,10 @@ export class SubHeader extends React.Component<Props, any> {
|
|||||||
|
|
||||||
private renderItems(): any {
|
private renderItems(): any {
|
||||||
const { selectedExpKey } = this.props.AppState;
|
const { selectedExpKey } = this.props.AppState;
|
||||||
return _.map(this.props.AppState.expansions, (exp, key) => {
|
return _.map(this.props.AppState.expansions, (_, key) => {
|
||||||
return (
|
return (
|
||||||
<div key={key} className={'sub-header__item ' + (key === selectedExpKey && 'selected')} onClick={() => this.selectExpansion(key)}>
|
<div key={key} className={'sub-header__item ' + (key === selectedExpKey && 'selected')} onClick={() => this.selectExpansion(key)}>
|
||||||
<div style={{ textAlign: 'center' }}>{exp.name}</div>
|
<img src={images[key]} className="exp-image"/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,10 +21,30 @@ body {
|
|||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: $blue;
|
color: $blue;
|
||||||
transition: all 0.1s linear;
|
transition: all 0.2s linear;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $blue--lighter;
|
color: $blue--lighter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track
|
||||||
|
{
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar
|
||||||
|
{
|
||||||
|
width: 5px;
|
||||||
|
height: 5px;
|
||||||
|
background-color: none;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb
|
||||||
|
{
|
||||||
|
border-radius: 10px;
|
||||||
|
background-color: darken($dark-blue, 5%);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
|
import { remote } from 'electron';
|
||||||
|
import * as _ from 'lodash';
|
||||||
import { action, computed, observable, runInAction } from 'mobx';
|
import { action, computed, observable, runInAction } from 'mobx';
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
import { persistentStateSeed } from './persistent-state-seed';
|
||||||
|
|
||||||
export interface ExpansionType {
|
export interface ExpansionType {
|
||||||
name: string;
|
name: string;
|
||||||
servers: ServerType[];
|
servers: ServerType[];
|
||||||
directory?: string;
|
directory?: string;
|
||||||
|
selectedServerIndex?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ServerType {
|
export interface ServerType {
|
||||||
@@ -14,47 +18,39 @@ export interface ServerType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class AppState {
|
export class AppState {
|
||||||
|
private appPath: string;
|
||||||
|
private persistentFilePath: string;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
this.appPath = remote.app.getPath('appData') + '/' + remote.app.getName();
|
||||||
|
this.persistentFilePath = this.appPath + '/state.json';
|
||||||
this.bootstrap();
|
this.bootstrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@observable public expansions: { [key: string]: ExpansionType };
|
||||||
private bootstrap(): void {
|
@observable public isBootstrapped: boolean = false;
|
||||||
fs.readFile('./servers.json', (err, data) => {
|
@observable public selectedExpKey: string = 'vanilla';
|
||||||
if (!err) {
|
|
||||||
runInAction(() => {
|
|
||||||
this.expansions = JSON.parse(data.toString()) as any;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@observable
|
|
||||||
public expansions: { [key: string]: ExpansionType } = {
|
|
||||||
vanilla: {
|
|
||||||
name: 'Vanilla',
|
|
||||||
servers: [],
|
|
||||||
directory: '',
|
|
||||||
},
|
|
||||||
bc: {
|
|
||||||
name: 'Burning Crusade',
|
|
||||||
servers: [],
|
|
||||||
directory: '',
|
|
||||||
},
|
|
||||||
wotlk: {
|
|
||||||
name: 'Wrath of the Lich King',
|
|
||||||
servers: [],
|
|
||||||
directory: '',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
@observable
|
|
||||||
public selectedExpKey: string = 'vanilla';
|
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
public get selectedExpansion(): ExpansionType {
|
public get selectedExpansion(): ExpansionType {
|
||||||
return this.expansions[this.selectedExpKey];
|
return _.get(this.expansions, `[${this.selectedExpKey}]`);
|
||||||
|
}
|
||||||
|
|
||||||
|
@computed
|
||||||
|
public get selectedServer(): ServerType {
|
||||||
|
|
||||||
|
if (this.selectedExpansion.servers.length < 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const index: number = this.selectedExpansion.selectedServerIndex;
|
||||||
|
return this.selectedExpansion.servers[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
public setSelectedServerIndex(index: number): void {
|
||||||
|
this.selectedExpansion.selectedServerIndex = index;
|
||||||
|
this.updateFile(this.expansions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@@ -64,18 +60,47 @@ export class AppState {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
public setDirectory(dir: string): void {
|
public setDirectory(dir: string): void {
|
||||||
this.expansions[this.selectedExpKey].directory = dir;
|
this.selectedExpansion.directory = dir;
|
||||||
this.updateFile(this.expansions);
|
this.updateFile(this.expansions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// bootstrap application
|
||||||
|
// creates directory and state.json in appData
|
||||||
|
@action
|
||||||
|
private bootstrap(): void {
|
||||||
|
if (!fs.statSync(this.appPath).isDirectory()) {
|
||||||
|
fs.mkdirSync(this.appPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.stat(this.persistentFilePath, err => {
|
||||||
|
// create file if not exists
|
||||||
|
if (err) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.expansions = persistentStateSeed();
|
||||||
|
this.isBootstrapped = true;
|
||||||
|
});
|
||||||
|
this.updateFile(this.expansions);
|
||||||
|
} else {
|
||||||
|
fs.readFile(this.persistentFilePath, (err, data) => {
|
||||||
|
if (!err) {
|
||||||
|
runInAction(() => {
|
||||||
|
this.expansions = JSON.parse(data.toString()) as any;
|
||||||
|
this.isBootstrapped = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private updateFile(exp: any): Promise<void> {
|
private updateFile(exp: any): Promise<void> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fs.writeFile('./servers.json', JSON.stringify(exp, null, 2), {}, (err) => {
|
fs.writeFile(this.persistentFilePath, JSON.stringify(exp, null, 2), {}, err => {
|
||||||
err ? reject(err) : resolve();
|
err ? reject(err) : resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new AppState();
|
export default new AppState();
|
||||||
|
|||||||
39
app/state/persistent-state-seed.ts
Normal file
39
app/state/persistent-state-seed.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// object is used to create state.json inside user data directory
|
||||||
|
export const persistentStateSeed = (): any => {
|
||||||
|
return {
|
||||||
|
vanilla: {
|
||||||
|
name: 'Vanilla',
|
||||||
|
servers: [
|
||||||
|
{
|
||||||
|
name: 'Lights Hope',
|
||||||
|
realmlist: 'logon.lightshope.org',
|
||||||
|
website: 'www.lightshope.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Elysium',
|
||||||
|
realmlist: '',
|
||||||
|
website: 'www.elysium-project.org',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Kronos',
|
||||||
|
realmlist: 'login.kronos-wow.com',
|
||||||
|
website: 'www.kronos-wow.com',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
directory: '',
|
||||||
|
selectedServerIndex: 0,
|
||||||
|
},
|
||||||
|
bc: {
|
||||||
|
name: 'Burning Crusade',
|
||||||
|
servers: [] as any,
|
||||||
|
directory: '',
|
||||||
|
selectedServerIndex: 0,
|
||||||
|
},
|
||||||
|
wotlk: {
|
||||||
|
name: 'Wrath of the Lich King',
|
||||||
|
servers: [] as any,
|
||||||
|
directory: '',
|
||||||
|
selectedServerIndex: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
BIN
docs/images/prototype2.PNG
Normal file
BIN
docs/images/prototype2.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 127 KiB |
@@ -4,7 +4,7 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app" style="height: 100%"></div>
|
<div id="app" style="height: 100%; overflow: hidden"></div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
16
main.js
16
main.js
@@ -16,15 +16,15 @@ function createWindow() {
|
|||||||
mainWindow = new BrowserWindow({ width: 800, height: 600, frame: false });
|
mainWindow = new BrowserWindow({ width: 800, height: 600, frame: false });
|
||||||
|
|
||||||
// and load the index.html of the app.
|
// and load the index.html of the app.
|
||||||
// mainWindow.loadURL(
|
mainWindow.loadURL(
|
||||||
// url.format({
|
url.format({
|
||||||
// pathname: path.join(__dirname, './dist/index.html'),
|
pathname: path.join(__dirname, './dist/index.html'),
|
||||||
// protocol: 'file:',
|
protocol: 'file:',
|
||||||
// slashes: true,
|
slashes: true,
|
||||||
// }),
|
}),
|
||||||
// );
|
);
|
||||||
|
|
||||||
mainWindow.loadURL('http://localhost:8080');
|
// mainWindow.loadURL('http://localhost:8080');
|
||||||
|
|
||||||
// Open the DevTools.
|
// Open the DevTools.
|
||||||
// mainWindow.webContents.openDevTools()
|
// mainWindow.webContents.openDevTools()
|
||||||
|
|||||||
31
package.json
31
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "todoapp",
|
"name": "ps-launcher",
|
||||||
"version": "1.0.0",
|
"version": "0.0.1",
|
||||||
"description": "A seed for a simple react application with typescript.",
|
"description": "A seed for a simple react application with typescript.",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -8,8 +8,25 @@
|
|||||||
"c9": "webpack-dev-server --host 0.0.0.0 --port 8080 --inline --history-api-fallback",
|
"c9": "webpack-dev-server --host 0.0.0.0 --port 8080 --inline --history-api-fallback",
|
||||||
"dev": "webpack --watch --colors",
|
"dev": "webpack --watch --colors",
|
||||||
"dev:server": "webpack-dev-server --inline --history-api-fallback",
|
"dev:server": "webpack-dev-server --inline --history-api-fallback",
|
||||||
"start": "electron ./main.js",
|
"start": "electron .",
|
||||||
"watch": "webpack --watch"
|
"watch": "webpack --watch",
|
||||||
|
"pack": "electron-builder --dir",
|
||||||
|
"dist": "electron-builder"
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"appId": "ps-launcher",
|
||||||
|
"directories": {
|
||||||
|
"output": "build"
|
||||||
|
},
|
||||||
|
"win": {
|
||||||
|
"target": "nsis"
|
||||||
|
},
|
||||||
|
"nsis": {
|
||||||
|
"oneClick": false,
|
||||||
|
"perMachine": true,
|
||||||
|
"runAfterFinish": true,
|
||||||
|
"deleteAppDataOnUninstall": true
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"author": "Mitchell Gerber",
|
"author": "Mitchell Gerber",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -29,7 +46,7 @@
|
|||||||
"babel-preset-stage-0": "^6.16.0",
|
"babel-preset-stage-0": "^6.16.0",
|
||||||
"clean-webpack-plugin": "^0.1.14",
|
"clean-webpack-plugin": "^0.1.14",
|
||||||
"css-loader": "^0.28.7",
|
"css-loader": "^0.28.7",
|
||||||
"electron": "^1.7.9",
|
"electron-builder-squirrel-windows": "^19.39.0",
|
||||||
"extract-text-webpack-plugin": "3.0.1",
|
"extract-text-webpack-plugin": "3.0.1",
|
||||||
"file-loader": "^1.1.5",
|
"file-loader": "^1.1.5",
|
||||||
"font-awesome": "^4.7.0",
|
"font-awesome": "^4.7.0",
|
||||||
@@ -51,5 +68,9 @@
|
|||||||
"url-loader": "^0.6.2",
|
"url-loader": "^0.6.2",
|
||||||
"webpack": "3.7.1",
|
"webpack": "3.7.1",
|
||||||
"webpack-dev-server": "2.9.2"
|
"webpack-dev-server": "2.9.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"electron": "^1.7.9",
|
||||||
|
"electron-builder": "^19.37.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
servers.json
28
servers.json
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"vanilla": {
|
|
||||||
"name": "Vanilla",
|
|
||||||
"servers": [
|
|
||||||
{
|
|
||||||
"name": "Elysium",
|
|
||||||
"realmlist": "",
|
|
||||||
"website": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Kronos",
|
|
||||||
"realmlist": "",
|
|
||||||
"website": ""
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"directory": ""
|
|
||||||
},
|
|
||||||
"bc": {
|
|
||||||
"name": "Burning Crusade",
|
|
||||||
"servers": [],
|
|
||||||
"directory": ""
|
|
||||||
},
|
|
||||||
"wotlk": {
|
|
||||||
"name": "Wrath of the Lich King",
|
|
||||||
"servers": [],
|
|
||||||
"directory": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -43,28 +43,31 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.svg$/,
|
test: /\.svg$/,
|
||||||
use:
|
use: 'url-loader?limit=65000&mimetype=image/svg+xml&name=static/[name].[hash].[ext]',
|
||||||
'url-loader?limit=65000&mimetype=image/svg+xml&name=static/[name].[hash].[ext]',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.woff$/,
|
test: /\.woff$/,
|
||||||
use:
|
use: 'url-loader?limit=65000&mimetype=application/font-woff&name=static/[name].[hash].[ext]',
|
||||||
'url-loader?limit=65000&mimetype=application/font-woff&name=static/[name].[hash].[ext]',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.woff2$/,
|
test: /\.woff2$/,
|
||||||
use:
|
use: 'url-loader?limit=65000&mimetype=application/font-woff2&name=static/[name].[hash].[ext]',
|
||||||
'url-loader?limit=65000&mimetype=application/font-woff2&name=static/[name].[hash].[ext]',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.[ot]tf$/,
|
test: /\.[ot]tf$/,
|
||||||
use:
|
use: 'url-loader?limit=65000&mimetype=application/octet-stream&name=static/[name].[hash].[ext]',
|
||||||
'url-loader?limit=65000&mimetype=application/octet-stream&name=static/[name].[hash].[ext]',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.eot$/,
|
test: /\.eot$/,
|
||||||
use:
|
use: 'url-loader?limit=65000&mimetype=application/vnd.ms-fontobject&name=static/[name].[hash].[ext]',
|
||||||
'url-loader?limit=65000&mimetype=application/vnd.ms-fontobject&name=static/[name].[hash].[ext]',
|
},
|
||||||
|
{
|
||||||
|
test: /\.(?:png|jpg|svg)$/,
|
||||||
|
loader: 'file-loader',
|
||||||
|
query: {
|
||||||
|
// Inline images smaller than 10kb as data URIs
|
||||||
|
limit: 10000,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -86,5 +89,8 @@ module.exports = {
|
|||||||
minChunks: 'Infinity',
|
minChunks: 'Infinity',
|
||||||
}),
|
}),
|
||||||
new webpack.HotModuleReplacementPlugin(),
|
new webpack.HotModuleReplacementPlugin(),
|
||||||
|
new webpack.DefinePlugin({
|
||||||
|
VERSION: JSON.stringify(require("./package.json").version)
|
||||||
|
})
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user