mirror of
https://github.com/mgerb/ps-launcher
synced 2026-01-09 01:52:57 +00:00
coming along well - electron is pretty nice
This commit is contained in:
@@ -1 +1,5 @@
|
|||||||
# Work in progress
|
# Work in progress
|
||||||
|
|
||||||
|
## Early Prototype 10/17/2017
|
||||||
|
|
||||||
|

|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
|
||||||
|
|
||||||
import { Header } from './components/Header';
|
|
||||||
import Home from './pages/Home/Home';
|
|
||||||
|
|
||||||
// styling
|
|
||||||
import './scss/index.scss';
|
|
||||||
|
|
||||||
interface Props {}
|
|
||||||
|
|
||||||
interface State {}
|
|
||||||
|
|
||||||
export default class Wrapper extends React.Component<Props, State> {
|
|
||||||
constructor(props: Props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
public render() {
|
|
||||||
return (
|
|
||||||
<BrowserRouter>
|
|
||||||
<div>
|
|
||||||
<Header />
|
|
||||||
<Switch>
|
|
||||||
{/* <Route exact path="/" component={} /> */}
|
|
||||||
<Route component={Home} />
|
|
||||||
</Switch>
|
|
||||||
</div>
|
|
||||||
</BrowserRouter>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
5
app/Wrapper/Wrapper.scss
Normal file
5
app/Wrapper/Wrapper.scss
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
.wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
26
app/Wrapper/Wrapper.tsx
Normal file
26
app/Wrapper/Wrapper.tsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Provider } from 'mobx-react';
|
||||||
|
import AppState from '../state/AppState';
|
||||||
|
import { Content, Header, ServerList, SubHeader } from '../components';
|
||||||
|
|
||||||
|
import './Wrapper.scss';
|
||||||
|
|
||||||
|
const stores = { AppState };
|
||||||
|
|
||||||
|
export class Wrapper extends React.Component<any, any> {
|
||||||
|
|
||||||
|
public render(): any {
|
||||||
|
return (
|
||||||
|
<Provider {...stores}>
|
||||||
|
<div className="wrapper">
|
||||||
|
<Header />
|
||||||
|
<SubHeader />
|
||||||
|
<div style={{ display: 'flex', flex: 1 }}>
|
||||||
|
<ServerList />
|
||||||
|
<Content />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import Wrapper from './Wrapper';
|
import { Wrapper } from './Wrapper/Wrapper';
|
||||||
import 'babel-polyfill';
|
import 'babel-polyfill';
|
||||||
|
|
||||||
|
// base styling
|
||||||
|
import './scss/index.scss';
|
||||||
|
|
||||||
ReactDOM.render(<Wrapper />, document.getElementById('app'));
|
ReactDOM.render(<Wrapper />, document.getElementById('app'));
|
||||||
|
|||||||
36
app/components/Content/Content.scss
Normal file
36
app/components/Content/Content.scss
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
@import '../../scss/variables';
|
||||||
|
|
||||||
|
.content {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.path-container {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-button {
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: $blue;
|
||||||
|
transition: background 0.2s;
|
||||||
|
outline: none;
|
||||||
|
padding: 0 15px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: darken($blue, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-input {
|
||||||
|
flex: 1;
|
||||||
|
background: darken($dark-blue, 3%);
|
||||||
|
border: none;
|
||||||
|
color: $blue--lighter;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
&::-webkit-input-placeholder {
|
||||||
|
color: $dark-blue--2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
86
app/components/Content/Content.tsx
Normal file
86
app/components/Content/Content.tsx
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
import React from 'react';
|
||||||
|
// import fs from 'fs';
|
||||||
|
// import { exec } from 'child_process';
|
||||||
|
import { inject, observer } from 'mobx-react';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
import { AppState } from '../../state/AppState';
|
||||||
|
|
||||||
|
import './Content.scss';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
AppState?: AppState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@inject('AppState')
|
||||||
|
@observer
|
||||||
|
export class Content extends React.Component<Props, any> {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.state = {
|
||||||
|
path: '',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 {
|
||||||
|
const path: string = _.get(e, `target.files[0].path`);
|
||||||
|
|
||||||
|
if (path) {
|
||||||
|
this.props.AppState.setDirectory(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private onInputChange(e: any): void {
|
||||||
|
this.props.AppState.setDirectory(e.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): any {
|
||||||
|
const { selectedExpansion } = this.props.AppState;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="content">
|
||||||
|
<div className="path-container">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="content-input"
|
||||||
|
placeholder="Your wow directory"
|
||||||
|
value={selectedExpansion.directory}
|
||||||
|
onChange={this.onInputChange.bind(this)}
|
||||||
|
/>
|
||||||
|
<label htmlFor="folder-browser" className="content-button">
|
||||||
|
Browse
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="folder-browser"
|
||||||
|
type="file"
|
||||||
|
{...{ webkitdirectory: 'true' }}
|
||||||
|
onChange={this.onFolderSelect.bind(this)}
|
||||||
|
style={{ display: 'none' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
@import '../../scss/variables.scss';
|
@import '../../scss/variables.scss';
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
background: $dark-blue--1;
|
background: $dark-blue--2;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 40px;
|
height: 30px;
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
|
border-bottom: 1px solid $dark-blue--3;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header__draggable-region {
|
.header__draggable-region {
|
||||||
|
|||||||
@@ -1,14 +1,26 @@
|
|||||||
import { remote } from 'electron';
|
import { remote } from 'electron';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { observer, inject } from 'mobx-react';
|
||||||
|
import { AppState } from '../../state/AppState';
|
||||||
import './Header.scss';
|
import './Header.scss';
|
||||||
|
|
||||||
export class Header extends React.Component<any, any> {
|
interface Props {
|
||||||
|
AppState?: AppState;
|
||||||
|
}
|
||||||
|
|
||||||
exit() {
|
@inject('AppState')
|
||||||
|
@observer
|
||||||
|
export class Header extends React.Component<Props, any> {
|
||||||
|
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
private exit(): void {
|
||||||
window.close();
|
window.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
maximize() {
|
private maximize(): void {
|
||||||
if (remote.getCurrentWindow().isMaximized()) {
|
if (remote.getCurrentWindow().isMaximized()) {
|
||||||
remote.getCurrentWindow().restore();
|
remote.getCurrentWindow().restore();
|
||||||
} else {
|
} else {
|
||||||
@@ -16,14 +28,14 @@ export class Header extends React.Component<any, any> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
minimize() {
|
private minimize(): void {
|
||||||
remote.getCurrentWindow().minimize();
|
remote.getCurrentWindow().minimize();
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
public render(): any {
|
||||||
return (
|
return (
|
||||||
<div className="header">
|
<div className="header">
|
||||||
<div className="header__draggable-region"/>
|
<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)}/>
|
||||||
<div className="fa fa-times fa-lg header-icon" onClick={() => this.exit()}/>
|
<div className="fa fa-times fa-lg header-icon" onClick={() => this.exit()}/>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
export * from './Header';
|
|
||||||
7
app/components/ServerList/ServerList.scss
Normal file
7
app/components/ServerList/ServerList.scss
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@import '../../scss/variables.scss';
|
||||||
|
|
||||||
|
.server-list {
|
||||||
|
background: darken($dark-blue, 1%);
|
||||||
|
width: 200px;
|
||||||
|
border-right: 1px solid $dark-blue--3;
|
||||||
|
}
|
||||||
24
app/components/ServerList/ServerList.tsx
Normal file
24
app/components/ServerList/ServerList.tsx
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { inject, observer } from 'mobx-react';
|
||||||
|
import { AppState } from '../../state/AppState';
|
||||||
|
|
||||||
|
import './ServerList.scss';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
AppState?: AppState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@inject('AppState')
|
||||||
|
@observer
|
||||||
|
export class ServerList extends React.Component<Props, any> {
|
||||||
|
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): any {
|
||||||
|
return (
|
||||||
|
<div className="server-list">Server list</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
22
app/components/SubHeader/SubHeader.scss
Normal file
22
app/components/SubHeader/SubHeader.scss
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
@import '../../scss/variables.scss';
|
||||||
|
|
||||||
|
.sub-header {
|
||||||
|
background: $dark-blue--1;
|
||||||
|
border-bottom: 1px solid $dark-blue--3;
|
||||||
|
display: flex;
|
||||||
|
height: 100px;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.sub-header__item {
|
||||||
|
width: 100px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover, &.selected {
|
||||||
|
background: $dark-blue--3;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
45
app/components/SubHeader/SubHeader.tsx
Normal file
45
app/components/SubHeader/SubHeader.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { inject, observer } from 'mobx-react';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
import { AppState } from '../../state/AppState';
|
||||||
|
|
||||||
|
import './SubHeader.scss';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
AppState?: AppState;
|
||||||
|
}
|
||||||
|
|
||||||
|
@inject('AppState')
|
||||||
|
@observer
|
||||||
|
export class SubHeader extends React.Component<Props, any> {
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
}
|
||||||
|
|
||||||
|
public componentDidMount(): void {
|
||||||
|
this.renderItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
private selectExpansion(exp: string): void {
|
||||||
|
this.props.AppState.setSelectedExpansion(exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderItems(): any {
|
||||||
|
const { selectedExpKey } = this.props.AppState;
|
||||||
|
return _.map(this.props.AppState.expansions, (exp, key) => {
|
||||||
|
return (
|
||||||
|
<div key={key} className={'sub-header__item ' + (key === selectedExpKey && 'selected')} onClick={() => this.selectExpansion(key)}>
|
||||||
|
<div style={{ textAlign: 'center' }}>{exp.name}</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): any {
|
||||||
|
return (
|
||||||
|
<div className="sub-header">
|
||||||
|
{this.renderItems()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
4
app/components/index.ts
Normal file
4
app/components/index.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export * from './Content/Content';
|
||||||
|
export * from './Header/Header';
|
||||||
|
export * from './ServerList/ServerList';
|
||||||
|
export * from './SubHeader/SubHeader';
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
.Home {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import * as _ from 'lodash';
|
|
||||||
import fs from 'fs';
|
|
||||||
import { exec } from 'child_process';
|
|
||||||
import React from 'react';
|
|
||||||
import { RouteComponentProps } from 'react-router-dom';
|
|
||||||
|
|
||||||
import './Home.scss';
|
|
||||||
|
|
||||||
interface Props extends RouteComponentProps<any> {}
|
|
||||||
|
|
||||||
interface State {
|
|
||||||
path: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class Home extends React.Component<Props, State> {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.state = {
|
|
||||||
path: '',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onFolderSelect(e: React.ChangeEvent<HTMLInputElement>) {
|
|
||||||
const path: string = _.get(e, `target.files[0].path`);
|
|
||||||
|
|
||||||
if (path) {
|
|
||||||
this.setState({ path });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async startGame() {
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { path } = this.state;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="Home">
|
|
||||||
<div>{path}</div>
|
|
||||||
{/* hacky way of adding webkitdirectory to the input */}
|
|
||||||
<input type="file" {...{ webkitdirectory: 'true' }} onChange={this.onFolderSelect.bind(this)} />
|
|
||||||
<div>
|
|
||||||
<button onClick={this.startGame.bind(this)}>Start</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
.NotFound {
|
|
||||||
font-size: 20px;
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 200px;
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { RouteComponentProps } from 'react-router-dom';
|
|
||||||
|
|
||||||
import './NotFound.scss';
|
|
||||||
|
|
||||||
interface Props extends RouteComponentProps<any> {}
|
|
||||||
|
|
||||||
interface State {}
|
|
||||||
|
|
||||||
export default class NotFound extends React.Component<Props, State> {
|
|
||||||
constructor(props: Props) {
|
|
||||||
super(props);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return <div className="NotFound">404 Not Found</div>;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +1,15 @@
|
|||||||
|
* {
|
||||||
|
&:focus {
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
font-family: 'Roboto Condensed', sans-serif;
|
font-family: 'Roboto Condensed', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
color: $light-blue;
|
color: $white;
|
||||||
background-color: $dark-blue;
|
background-color: $dark-blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
$dark-blue: #1d2938;
|
$dark-blue: #1d2938;
|
||||||
$dark-blue--1: lighten(#1d2938, 5%);
|
$dark-blue--1: lighten(#1d2938, 5%);
|
||||||
$dark-blue--2: lighten(#1d2938, 10%);
|
$dark-blue--2: lighten(#1d2938, 10%);
|
||||||
|
$dark-blue--3: lighten(#1d2938, 15%);
|
||||||
$blue: #258de5;
|
$blue: #258de5;
|
||||||
$blue--lighter: saturate(lighten($blue, 10%), 100%);
|
$blue--lighter: saturate(lighten($blue, 10%), 100%);
|
||||||
$green: #39ce83;
|
$green: #39ce83;
|
||||||
$light-blue: #e9eef2;
|
|
||||||
$red: #e95779;
|
$red: #e95779;
|
||||||
$white: #fff;
|
$white: darken(#e9eef2, 10%);
|
||||||
|
|||||||
81
app/state/AppState.ts
Normal file
81
app/state/AppState.ts
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
import { action, computed, observable, runInAction } from 'mobx';
|
||||||
|
import fs from 'fs';
|
||||||
|
|
||||||
|
export interface ExpansionType {
|
||||||
|
name: string;
|
||||||
|
servers: ServerType[];
|
||||||
|
directory?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServerType {
|
||||||
|
name: string;
|
||||||
|
realmlist: string;
|
||||||
|
website: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AppState {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.bootstrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
private bootstrap(): void {
|
||||||
|
fs.readFile('./servers.json', (err, data) => {
|
||||||
|
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
|
||||||
|
public get selectedExpansion(): ExpansionType {
|
||||||
|
return this.expansions[this.selectedExpKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
public setSelectedExpansion(exp: string): void {
|
||||||
|
this.selectedExpKey = exp;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
public setDirectory(dir: string): void {
|
||||||
|
this.expansions[this.selectedExpKey].directory = dir;
|
||||||
|
this.updateFile(this.expansions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private updateFile(exp: any): Promise<void> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.writeFile('./servers.json', JSON.stringify(exp, null, 2), {}, (err) => {
|
||||||
|
err ? reject(err) : resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new AppState();
|
||||||
BIN
docs/images/prototype1.PNG
Normal file
BIN
docs/images/prototype1.PNG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
@@ -4,7 +4,7 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app" style="height: 100%"></div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -35,12 +35,13 @@
|
|||||||
"font-awesome": "^4.7.0",
|
"font-awesome": "^4.7.0",
|
||||||
"html-webpack-plugin": "^2.24.1",
|
"html-webpack-plugin": "^2.24.1",
|
||||||
"lodash": "^4.17.4",
|
"lodash": "^4.17.4",
|
||||||
|
"mobx": "^3.3.1",
|
||||||
|
"mobx-react": "^4.3.3",
|
||||||
"node-sass": "^4.5.3",
|
"node-sass": "^4.5.3",
|
||||||
"normalize.css": "^7.0.0",
|
"normalize.css": "^7.0.0",
|
||||||
"prettier": "^1.7.4",
|
"prettier": "^1.7.4",
|
||||||
"react": "^16.0.0",
|
"react": "^16.0.0",
|
||||||
"react-dom": "^16.0.0",
|
"react-dom": "^16.0.0",
|
||||||
"react-router-dom": "^4.2.2",
|
|
||||||
"sass-loader": "^6.0.6",
|
"sass-loader": "^6.0.6",
|
||||||
"style-loader": "^0.19.0",
|
"style-loader": "^0.19.0",
|
||||||
"ts-loader": "^2.0.3",
|
"ts-loader": "^2.0.3",
|
||||||
|
|||||||
28
servers.json
Normal file
28
servers.json
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"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": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
"module": "es6",
|
"module": "es6",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
@@ -7,7 +8,7 @@
|
|||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"noImplicitThis": true,
|
"noImplicitThis": true,
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": false,
|
||||||
"preserveConstEnums": true,
|
"preserveConstEnums": true,
|
||||||
"allowJs": false,
|
"allowJs": false,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"extends": "tslint-config-airbnb",
|
"extends": "tslint-config-airbnb",
|
||||||
"rules": {
|
"rules": {
|
||||||
|
"member-access": true,
|
||||||
|
"typedef": [true, "call-signature", "member-variable-declaration"],
|
||||||
|
"quotemark": [true, "single", "jsx-double"],
|
||||||
"align": false,
|
"align": false,
|
||||||
"ter-arrow-parens": false,
|
"ter-arrow-parens": false,
|
||||||
"import-name": false,
|
"import-name": false,
|
||||||
|
|||||||
71
yarn.lock
71
yarn.lock
@@ -2564,16 +2564,6 @@ he@1.1.x:
|
|||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
|
||||||
|
|
||||||
history@^4.7.2:
|
|
||||||
version "4.7.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/history/-/history-4.7.2.tgz#22b5c7f31633c5b8021c7f4a8a954ac139ee8d5b"
|
|
||||||
dependencies:
|
|
||||||
invariant "^2.2.1"
|
|
||||||
loose-envify "^1.2.0"
|
|
||||||
resolve-pathname "^2.2.0"
|
|
||||||
value-equal "^0.4.0"
|
|
||||||
warning "^3.0.0"
|
|
||||||
|
|
||||||
hmac-drbg@^1.0.0:
|
hmac-drbg@^1.0.0:
|
||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
|
||||||
@@ -2590,7 +2580,7 @@ hoek@4.x.x:
|
|||||||
version "4.2.0"
|
version "4.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
|
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
|
||||||
|
|
||||||
hoist-non-react-statics@^2.3.0:
|
hoist-non-react-statics@^2.3.1:
|
||||||
version "2.3.1"
|
version "2.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
|
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz#343db84c6018c650778898240135a1420ee22ce0"
|
||||||
|
|
||||||
@@ -2777,7 +2767,7 @@ interpret@^1.0.0:
|
|||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0"
|
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0"
|
||||||
|
|
||||||
invariant@^2.2.1, invariant@^2.2.2:
|
invariant@^2.2.2:
|
||||||
version "2.2.2"
|
version "2.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
|
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3193,7 +3183,7 @@ longest@^1.0.1:
|
|||||||
version "1.0.1"
|
version "1.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
|
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
|
||||||
|
|
||||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1:
|
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1:
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3372,6 +3362,16 @@ mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkd
|
|||||||
dependencies:
|
dependencies:
|
||||||
minimist "0.0.8"
|
minimist "0.0.8"
|
||||||
|
|
||||||
|
mobx-react@^4.3.3:
|
||||||
|
version "4.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/mobx-react/-/mobx-react-4.3.3.tgz#4ad76c03d1e942b431e942f9ea18df0756771655"
|
||||||
|
dependencies:
|
||||||
|
hoist-non-react-statics "^2.3.1"
|
||||||
|
|
||||||
|
mobx@^3.3.1:
|
||||||
|
version "3.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/mobx/-/mobx-3.3.1.tgz#c38fc1a287a0dda3f5d4b85efe1137fedd9dcdf0"
|
||||||
|
|
||||||
ms@0.7.1:
|
ms@0.7.1:
|
||||||
version "0.7.1"
|
version "0.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
|
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
|
||||||
@@ -3778,12 +3778,6 @@ path-to-regexp@0.1.7:
|
|||||||
version "0.1.7"
|
version "0.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
|
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
|
||||||
|
|
||||||
path-to-regexp@^1.7.0:
|
|
||||||
version "1.7.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d"
|
|
||||||
dependencies:
|
|
||||||
isarray "0.0.1"
|
|
||||||
|
|
||||||
path-type@^1.0.0:
|
path-type@^1.0.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
|
resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
|
||||||
@@ -4149,7 +4143,7 @@ promise@^7.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
asap "~2.0.3"
|
asap "~2.0.3"
|
||||||
|
|
||||||
prop-types@^15.5.4, prop-types@^15.6.0:
|
prop-types@^15.6.0:
|
||||||
version "15.6.0"
|
version "15.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
|
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.0.tgz#ceaf083022fc46b4a35f69e13ef75aed0d639856"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -4269,29 +4263,6 @@ react-dom@^16.0.0:
|
|||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
prop-types "^15.6.0"
|
prop-types "^15.6.0"
|
||||||
|
|
||||||
react-router-dom@^4.2.2:
|
|
||||||
version "4.2.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-4.2.2.tgz#c8a81df3adc58bba8a76782e946cbd4eae649b8d"
|
|
||||||
dependencies:
|
|
||||||
history "^4.7.2"
|
|
||||||
invariant "^2.2.2"
|
|
||||||
loose-envify "^1.3.1"
|
|
||||||
prop-types "^15.5.4"
|
|
||||||
react-router "^4.2.0"
|
|
||||||
warning "^3.0.0"
|
|
||||||
|
|
||||||
react-router@^4.2.0:
|
|
||||||
version "4.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/react-router/-/react-router-4.2.0.tgz#61f7b3e3770daeb24062dae3eedef1b054155986"
|
|
||||||
dependencies:
|
|
||||||
history "^4.7.2"
|
|
||||||
hoist-non-react-statics "^2.3.0"
|
|
||||||
invariant "^2.2.2"
|
|
||||||
loose-envify "^1.3.1"
|
|
||||||
path-to-regexp "^1.7.0"
|
|
||||||
prop-types "^15.5.4"
|
|
||||||
warning "^3.0.0"
|
|
||||||
|
|
||||||
react@^16.0.0:
|
react@^16.0.0:
|
||||||
version "16.0.0"
|
version "16.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/react/-/react-16.0.0.tgz#ce7df8f1941b036f02b2cca9dbd0cb1f0e855e2d"
|
resolved "https://registry.yarnpkg.com/react/-/react-16.0.0.tgz#ce7df8f1941b036f02b2cca9dbd0cb1f0e855e2d"
|
||||||
@@ -4541,10 +4512,6 @@ requires-port@1.0.x, requires-port@1.x.x:
|
|||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||||
|
|
||||||
resolve-pathname@^2.2.0:
|
|
||||||
version "2.2.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/resolve-pathname/-/resolve-pathname-2.2.0.tgz#7e9ae21ed815fd63ab189adeee64dc831eefa879"
|
|
||||||
|
|
||||||
resolve@^1.3.2:
|
resolve@^1.3.2:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86"
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86"
|
||||||
@@ -5295,10 +5262,6 @@ validate-npm-package-license@^3.0.1:
|
|||||||
spdx-correct "~1.0.0"
|
spdx-correct "~1.0.0"
|
||||||
spdx-expression-parse "~1.0.0"
|
spdx-expression-parse "~1.0.0"
|
||||||
|
|
||||||
value-equal@^0.4.0:
|
|
||||||
version "0.4.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-0.4.0.tgz#c5bdd2f54ee093c04839d71ce2e4758a6890abc7"
|
|
||||||
|
|
||||||
vary@~1.1.2:
|
vary@~1.1.2:
|
||||||
version "1.1.2"
|
version "1.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||||
@@ -5327,12 +5290,6 @@ vrsource-tslint-rules@^5.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslint "~5.1.0"
|
tslint "~5.1.0"
|
||||||
|
|
||||||
warning@^3.0.0:
|
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/warning/-/warning-3.0.0.tgz#32e5377cb572de4ab04753bdf8821c01ed605b7c"
|
|
||||||
dependencies:
|
|
||||||
loose-envify "^1.0.0"
|
|
||||||
|
|
||||||
watchpack@^1.4.0:
|
watchpack@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac"
|
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac"
|
||||||
|
|||||||
Reference in New Issue
Block a user