Merge pull request #14 from chaoticbackup/experimental

Experimental
This commit is contained in:
DanudeSandstorm 2017-11-11 22:08:21 -05:00 committed by GitHub
commit 1f6b0d11f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 253 additions and 253 deletions

View File

@ -1,3 +1,4 @@
{
"presets": ["es2015", "react", "stage-1"]
"presets": ["es2015", "react", "stage-1"],
"plugins": ["transform-decorators-legacy"]
}

View File

@ -1,10 +1,11 @@
{
"folders":
[
{
"path": "."
}
],
[
{
"path": ".",
"folder_exclude_patterns": ["build", "node_modules"]
}
],
"syntax_override":
{
"\\.js$":

View File

@ -13,24 +13,31 @@
"author": "Danude Sandstorm",
"license": "MIT",
"dependencies": {
"react": "^15.4.1",
"react-dom": "^15.4.1",
"react-interactive": "^0.5.1",
"react-router": "^3.0.0",
"lokijs": "^1.5.1",
"prop-types": "^15.6.0",
"mobx": "^3.3.1",
"mobx-react": "^4.3.3",
"react": "^16.0.0",
"react-dom": "^16.0.0",
"react-interactive": "^0.8.1",
"react-router": "^3.2.0",
"react-router-dom": "^4.2.2",
"rxjs": "^5.5.0",
"whatwg-fetch": "^2.0.3"
},
"devDependencies": {
"babel-core": "^6.21.0",
"babel-eslint": "^7.1.1",
"babel-eslint": "^8.0.0",
"babel-loader": "^6.2.10",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-preset-es2015": "^6.18.0",
"babel-preset-react": "^6.16.0",
"babel-preset-stage-1": "^6.16.0",
"eslint": "^3.12.2",
"eslint-config-airbnb": "^13.0.0",
"eslint": "^4.0.0",
"eslint-config-airbnb": "^16.0.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^2.2.3",
"eslint-plugin-react": "^6.8.0",
"eslint-plugin-jsx-a11y": "^6.0.0",
"eslint-plugin-react": "^7.0.0",
"webpack": "^1.14.0",
"webpack-dev-server": "^1.16.2"
}

View File

@ -1,4 +1,5 @@
import React, { PropTypes } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import Interactive from 'react-interactive';
import { Link } from 'react-router';
import s from './styles/app.style';

View File

@ -1,39 +0,0 @@
import React from 'react';
export const language = "ENG";
export const bkgrnd = "05";
export function ChangePage(asParams) {
let location = "#";
switch (asParams) {
case 'collect':
location = '/collection/';
break;
case 'register':
break;
case 'build':
location = 'http://www.tradecardsonline.com/?action=selectCard&goal=DK&game_id=82';
break;
case 'centerOval':
location = '/';
break;
case 'enterTheCode':
break;
case 'trade':
location = 'http://www.tradecardsonline.com/?action=selectCard&goal=&game_id=82';
break;
case 'portal':
location = '/portal/';
break;
case 'forum':
location = 'http://chaoticbackup.forumotion.com';
break;
case 'playNow':
location = 'http://www.tradecardsonline.com/?action=selectCard&goal=DK&game_id=82';
break;
default:
location = '/construction/';
break;
}
return location;
}

View File

@ -0,0 +1,86 @@
import loki from 'lokijs';
import {observable, autorun} from "mobx";
export default class CollectionDB {
@observable built = []; // Keeps track of what collections have been populated
constructor(API) {
this.api = API;
// ignoring persistence for now
// this.setupDB();
//autorun(() => console.log(this.creatures));
let db = new loki("chaotic_portal.db");
this.attacks = db.addCollection('attacks');
this.battlegear = db.addCollection('battlegear');
this.creatures = db.addCollection('creatures');
this.locations = db.addCollection('locations');
this.mugic = db.addCollection('mugic');
this.db = db;
}
// setupDB() {
// var self = this;
// let db = new loki("chaotic_portal.db", { autosave: true, autoload: true, autoloadCallback: databaseInitialize, autosaveInterval: 4000, persistenceMethod: 'localStorage' });
// this.db = db;
// let databaseInitialize = () => {
// var entries;
// if ((entries = db.getCollection("attacks")) === null)
// entries = db.addCollection("attacks");
// self.attacks = entries;
// if ((entries = db.getCollection("battlegear")) === null)
// entries = db.addCollection("battlegear");
// self.battlegear = entries;
// console.log(db.getCollection("creatures"));
// if ((entries = db.getCollection("creatures")) === null)
// entries = db.addCollection("creatures");
// self.creatures = db.addCollection('creatures');
// if ((entries = db.getCollection("locations")) === null)
// entries = db.addCollection("locations");
// self.locations = entries
// if ((entries = db.getCollection("mugic")) === null)
// entries = db.addCollection("mugic");
// self.mugic = entries;
// };
// }
setup(spreadsheet, callback) {
this.api.getSpreadsheet(spreadsheet, (data) => {
callback(data.map((item) => {
let temp = {};
delete item.content;
for (const key of Object.keys(item)) {
temp[key] = item[key].$t;
}
return temp;
}));
});
}
setupAttacks() {
}
setupBattleGear() {
}
setupCreatures(tribe="Generic") {
this.setup(this.api.urls.Creatures[tribe], (data) => {
this.creatures.insert(data);
this.built.push("creatures_"+tribe);
});
}
setupLocations() {
}
setupMugic(tribe) {
}
}

View File

@ -1,4 +1,5 @@
import React, { PropTypes } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import Interactive from 'react-interactive';
import { Link } from 'react-router';
import s from '../styles/exampleComponent.style';

View File

@ -1,4 +1,5 @@
import React, { PropTypes } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import Interactive from 'react-interactive';
import { Link } from 'react-router';
import s from '../styles/exampleTwoDeepComponent.style';

View File

@ -1,4 +1,5 @@
import React, { PropTypes } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import s from '../styles/pageNotFound.style';
const propTypes = {

View File

@ -1,39 +1,47 @@
import React from 'react';
import 'whatwg-fetch';
import CollectionDB from './CollectionDB';
import {observable} from "mobx";
class API {
@observable portal = null;
@observable cards = null;
@observable urls = null;
instance = null;
class URLS {
static base_url = "https://spreadsheets.google.com/feeds/list/";
static data_format = "/od6/public/values?alt=json";
// + "/od6/public/basic?alt=json"; // Alternate data format
static base_spreadsheet = "1cUNmwV693zl2zqbH_IG4Wz8o9Va_sOHe7pAZF6M59Es";
get base_image() { return "https://drive.google.com/uc?id="; }
// Singleton
static getInstance() {
if (!this.instance) { this.instance = new API(); }
return this.instance;
}
static path(spreadsheetID) {
return URLS.base_url + spreadsheetID + URLS.data_format;
return API.base_url + spreadsheetID + API.data_format;
}
constructor() {
// This sets up urls
this.urls = {};
var self = this;
this.getSpreadsheet(URLS.path(URLS.base_spreadsheet), function(data) {
data.forEach(function(d) {
if (!self.urls[d.gsx$type.$t]) self.urls[d.gsx$type.$t] = {};
self.urls[d.gsx$type.$t][d.gsx$subtype.$t] = d.gsx$url.$t;
// This sets up urls and kicks off db
let urls = {};
this.getSpreadsheet(API.path(API.base_spreadsheet), (data) => {
if (data == null) return;
data.forEach((d) => {
if (!urls[d.gsx$type.$t]) urls[d.gsx$type.$t] = {};
urls[d.gsx$type.$t][d.gsx$subtype.$t] = API.path(d.gsx$url.$t);
});
this.urls = urls;
this.setupDB();
});
}
// Singleton
instance = null;
static getInstance() {
if (!URLS.instance) { URLS.instance = new URLS(); }
return URLS.instance;
}
getSpreadsheet(spreadsheet, callback) {
fetch(spreadsheet)
.then(function(response) {
// console.log(response);
return response.json();
}).then(function(json) {
return callback(json.feed.entry);
@ -43,31 +51,17 @@ class URLS {
});
}
/* Creatures */
/* TODO remove legacy getters when introducing state management*/
get Creatures_Card_Data() {
return URLS.path("1fUFYhG1NLLkSTzrdbevm6ZMKNP6xLiKUZvM1sY10pVI");
setupDB() {
try {
this.portal = new CollectionDB(this, "portal");
this.cards = new CollectionDB(this, "cards");
}
catch (err) {
console.log('setting up database failed', err);
}
}
get Creatures() {
return {
'Overworld': URLS.path("1Z4_MmlV7uE34nLzrcxslqQKRwL4OBXNA15s7G8eteXU"),
'Underworld': URLS.path("1c_XAxQsDIWVdzUxWl5t-K_mQumNjX-yrg0X-0NsZVts"),
'Mipedian': URLS.path("1P4FKASfnhR46j2bqm89T9xhI1Yyyy-jiZ1CkRglSy2k"),
'Danian': URLS.path("1-Lz-itwOobEvqr8HSLFFwg3JFkT64NbwyGFEPfj9rxU")
};
}
get Mugic() {
return {
'Overworld': URLS.path("1KsVX5SkygwPP6I8yd6xgcN8gB746o_FTh6SK1TvAcbU"),
'Underworld': URLS.path("1F7FHlob52cb_7J65cddM3The7w-kFiStBRd5wm4JRlA"),
'Mipedian': URLS.path("1QDsiSUuBV_4Jn6mvl96EGU06XEoVqILGN4suYKvh9CA"),
'Danian': URLS.path("1tEuwPGixJH2A03YtYL6Ar-MSFvtfrlaveT98GwJhw1g"),
'Generic': URLS.path("1M9iAbpYAHq_ppwm0PZKUvZGfu-zbrK1CZMY16m4Plf8")
};
}
}
export default URLS.getInstance();
export default API.getInstance();
// export default new API();

View File

@ -1,4 +1,5 @@
import React, { PropTypes } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import s from '../styles/pageNotFound.style';
const propTypes = {

View File

@ -4,54 +4,20 @@ import { Link } from 'react-router';
import PageNotFound from '../../PageNotFound';
import API from '../../SpreadsheetData';
import s from '../../../styles/app.style';
import UnderConstruction from '../../UnderConstruction';
export default class Creatures extends React.Component {
constructor(props) {
super (props);
this.state = {tribe: '', creatures: {}};
}
componentWillReceiveProps(nextProps) {
this.getData(nextProps);
}
componentDidMount() {
this.getData(this.props);
}
// ** Process the tribe ** //
// /portal/Creatures/
// /portal/{Tribe}/Creatures/
// The first / gets counted
getData(props) {
if (props.children) return this.props = props;
let path = props.location.pathname.split("/");
if (path[path.length-1] == "") path.pop(); // Remove trailing backslash
// Set tribe
let tribe = (path.length === 4) ? path[2] : "All";
this.setState({tribe: tribe});
// For each tribe, get its spreadsheet, set the state
var self = this;
let urls = (tribe == "All") ? API.Creatures : {[tribe]: API.Creatures[tribe]};
Object.keys(urls).map((tribe) => {
API.getSpreadsheet(urls[tribe], (data) => {
self.setState({creatures:
Object.assign(self.state.creatures, {[tribe]: data})
});
});
});
// self.setState({creatures: this.state.creatures.concat([data])});
}
hacks(event) {
console.log(event);
this.setState({click: true});
}
render() {
if (this.props.children) {
return (<div>{this.props.children}</div>);
}
return (
<UnderConstruction location={this.props.location}/>
);
}
fakerender() {
if (this.props.children) {
return (<div>{this.props.children}</div>);
}

View File

@ -8,25 +8,16 @@ import s from '../../../styles/app.style';
export default class Mugic extends React.Component {
constructor(props) {
super (props);
this.tribe = '';
this.state = {mugic: {}};
}
componentDidMount() {
if (this.props.children) return;
var self = this;
let urls = (this.tribe == "All") ? API.Mugic : {[this.tribe]: API.Mugic[this.tribe]};
// For each tribe, get its spreadsheet, set the state
Object.keys(urls).map((tribe) => {
API.getSpreadsheet(urls[tribe], function(data) {
self.setState({mugic: Object.assign(self.state.mugic, {[tribe]: data})});
});
});
}
render() {
if (this.props.children) {
return (<div>{this.props.children}</div>);
}
return (
<UnderConstruction location={this.props.location}/>
);
}
fakerender() {
if (this.props.children) {
return (<div>{this.props.children}</div>);
}

View File

@ -1,38 +1,27 @@
import React from 'react';
import Interactive from 'react-interactive';
import { Link } from 'react-router';
// import {browserHistory} from 'react-router';
import PageNotFound from '../../PageNotFound';
import UnderConstruction from '../../UnderConstruction';
import API from '../../SpreadsheetData';
import s from '../../../styles/app.style';
import {observer, inject} from 'mobx-react';
@inject((stores, props, context) => props) @observer
export default class SingleCreature extends React.Component {
constructor(props) {
super (props);
this.state = {tribe: '', creature: null, card_data: null};
}
componentWillReceiveProps(nextProps) {
this.getData(nextProps);
}
componentDidMount() {
this.getData(this.props);
}
// ** Process the tribe ** //
// /portal/Creatures/{Tribe}/{Name}
// /portal/{Tribe}/Creatures/{Name}
// The first / gets counted
getData(props) {
let path = props.location.pathname.split("/");
render() {
const store = API;
let path = this.props.location.pathname.split("/");
if (path[path.length-1] == "") path.pop(); // Remove trailing backslash
// Path too long
if ( path.length !== 5 ) {
return;
return(<PageNotFound location={this.props.location}/>);
}
//Handle both url layouts
@ -40,86 +29,64 @@ export default class SingleCreature extends React.Component {
if (path[2] === "Creatures") return path[3];
if (path[3] === "Creatures") return path[2];
})();
this.setState({tribe: tribe});
var name = decodeURIComponent(path[4]);
var self = this;
API.getSpreadsheet(API.Creatures[tribe], (data) => {
data.map((item, i) => {
if (item.title.$t == name)
self.setState({creature: item });
});
// If no creature set as false
if (!self.state.creature) {
self.setState({creature: "n/a"});
}
});
API.getSpreadsheet(API.Creatures_Card_Data, (data) => {
data.map((item, i) => {
if (item.title.$t == name) self.setState({card_data: item });
});
// If no card_data set as false
if (!self.state.card_data) {
self.setState({card_data: "n/a"});
}
});
}
render() {
var self = this;
// Get spreadsheet data based on tribe/name
if (!(API.Creatures).hasOwnProperty(this.state.tribe)) {
return(
<PageNotFound location={this.props.location}/>
//return(browserHistory.push('/PageNotFound'));
);
if (store.urls === null ||
store.portal === null ||
store.cards === null) {
return (<span>Loading...</span>);
}
// creature is the object to be used in the jsx
var creature = this.state.creature;
var card_data = this.state.card_data;
// Todo this isn't needed for now (handled by routes)
// if (!store.urls.Creatures.hasOwnProperty(tribe)) {
// return (<span>Invalid Tribe: {tribe}</span>);
// }
// TODO separate loading of card_data
if (creature == "n/a" || card_data == "n/a") return(
<PageNotFound location={this.props.location}/>
);
if (!store.cards.built.includes("creatures_Cards")) {
store.cards.setupCreatures("Cards");
return (<span>Loading...</span>);
}
if (creature == null || card_data == null) return(
<span>Loading...</span>
);
if (!store.portal.built.includes("creatures_"+tribe)) {
store.portal.setupCreatures(tribe);
return (<span>Loading...</span>);
}
const elements = card_data.gsx$elements.$t.split(/[ ,]+/).map((item, i) => {
return <img className="icon" src={"/src/img/icons/elements/"+item.toLowerCase()+".png"} alt={item} key={i}></img>;
});
const creature = store.portal.creatures.findOne({'gsx$name': path[4]});
const card_data = store.cards.creatures.findOne({'gsx$name': path[4]});
if (!creature) {
return(<PageNotFound location={this.props.location}/>);
}
const locations = creature.gsx$location.$t.split(/[,]+\s*/).map((item, i) => {
const locations = creature.gsx$location.split(/[,]+\s*/).map((item, i) => {
return <p key={i}><Interactive as={Link} {...s.link} to={"/portal/Locations/"+item}><span>{item}</span></Interactive></p>;
});
const battlegear = creature.gsx$battlegear.$t.split(/[,]+\s*/).map((item, i) => {
const battlegear = creature.gsx$battlegear.split(/[,]+\s*/).map((item, i) => {
return <p key={i}><Interactive as={Link} {...s.link} to={"/portal/Battlegear/"+item}><span>{item}</span></Interactive></p>;
});
return(
<div className={"creature " + this.state.tribe.toLowerCase()}>
<h1>{creature.gsx$name.$t}</h1>
<img className="splash" src={API.base_image + creature.gsx$splash.$t}></img>
const elements = card_data.gsx$elements.split(/[ ,]+/).map((item, i) => {
return <img className="icon" src={"/src/img/icons/elements/"+item.toLowerCase()+".png"} alt={item} key={i}></img>;
});
return (
<div className={"creature " + tribe.toLowerCase()}>
<h1>{creature.gsx$name}</h1>
<img className="splash" src={store.base_image + creature.gsx$splash}></img>
<hr />
<div>
<strong>Appearance:</strong><br />
{creature.gsx$appearance.$t}
{creature.gsx$appearance}
</div>
<hr />
<div>
<strong>Background:</strong><br />
{creature.gsx$background.$t}
{creature.gsx$background}
</div>
<hr />
<div>
<strong>Details:</strong><br />
{creature.gsx$details.$t}
{creature.gsx$details}
</div>
<hr />
<div>
@ -134,62 +101,72 @@ export default class SingleCreature extends React.Component {
<hr />
<div>
<strong>Height (ft):</strong><br />
{creature.gsx$height.$t}
{creature.gsx$height}
</div>
<hr />
<div>
<strong>Special Abilities:</strong><br />
{creature.gsx$specialabilities.$t}
{creature.gsx$specialabilities}
</div>
<hr />
<div>
<strong>Weight (lb):</strong><br />
{creature.gsx$weight.$t}
{creature.gsx$weight}
</div>
<hr />
<div>
<strong>Special Abilities:</strong><br />
{creature.gsx$specialabilities}
</div>
<hr />
<div>
<strong>Weight (lb):</strong><br />
{creature.gsx$weight}
</div>
<hr />
<div>
<strong>Card ID: </strong>
{card_data.gsx$cardid.$t}
{card_data.gsx$cardid}
</div>
<hr />
<div>
<strong>Set: </strong>
{card_data.gsx$set.$t}
{card_data.gsx$set}
</div>
<hr />
<div>
<strong>Rarity: </strong>
{card_data.gsx$rarity.$t}
{card_data.gsx$rarity}
</div>
<hr />
<div>
<strong>Tribe: </strong>{this.state.tribe}
<img className="icon" src={"/src/img/icons/tribes/"+this.state.tribe.toLowerCase()+".png"}></img>
<strong>Tribe: </strong>{tribe}
<img className="icon" src={"/src/img/icons/tribes/"+tribe.toLowerCase()+".png"}></img>
</div>
<hr />
<div>
<strong>Ability:</strong><br />
{card_data.gsx$ability.$t}
{card_data.gsx$ability}
</div>
<hr />
<div>
<strong>Courage: </strong>
{card_data.gsx$courage.$t}
{card_data.gsx$courage}
</div>
<hr />
<div>
<strong>Power: </strong>
{card_data.gsx$power.$t}
{card_data.gsx$power}
</div>
<hr />
<div>
<strong>Speed: </strong>
{card_data.gsx$speed.$t}
{card_data.gsx$speed}
</div>
<hr />
<div>
<strong>Wisdom: </strong>
{card_data.gsx$wisdom.$t}
{card_data.gsx$wisdom}
</div>
<hr />
<div>
@ -198,17 +175,17 @@ export default class SingleCreature extends React.Component {
<hr />
<div>
<strong>Energy: </strong>
{card_data.gsx$energy.$t}
{card_data.gsx$energy}
</div>
<hr />
<div>
<strong>Flavortext:</strong><br />
{card_data.gsx$flavortext.$t}
{card_data.gsx$flavortext}
</div>
<hr />
<div>
<strong>Mugic Ability: </strong>
{card_data.gsx$mugicability.$t}
{card_data.gsx$mugicability}
</div>
</div>
);

View File

@ -8,6 +8,9 @@ import UnderConstruction from './components/UnderConstruction';
import ExampleComponent from './components/ExampleComponent';
import ExampleTwoDeepComponent from './components/ExampleTwoDeepComponent';
/* SpreadsheetData */
import API from './components/SpreadsheetData';
/* Home Page */
import Home from './components/Home';
@ -43,6 +46,8 @@ const routes = (
{/* Collection */}
<Route path="collection/" mapMenuTitle="Collection">
<IndexRoute component={CollectionHome} />
<Route path="*" component={PageNotFound} />
</Route>
{/* Portal */}
@ -168,6 +173,8 @@ const routes = (
</Route>
</Route>
<Route path="*" component={PageNotFound} />
</Route>
<Route path="*" component={PageNotFound} />
</Route>

View File

@ -19,6 +19,10 @@ export default {
extensions: ['', '.js', '.jsx'],
},
node: {
fs: 'empty'
},
plugins: process.argv.indexOf('-p') === -1 ? null : [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),