From 2fcf3557b43af99a425d2fc4bb7065d8e1362158 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 23 Oct 2017 00:10:38 -0400 Subject: [PATCH 1/3] [add] lokijs in-memory database --- chaotic-portal.sublime-project | 11 +-- package.json | 22 +++--- src/Base.js | 3 +- src/components/ExampleComponent.js | 3 +- src/components/ExampleTwoDeepComponent.js | 3 +- src/components/PageNotFound.js | 3 +- src/components/SpreadsheetData.js | 79 +++++++++------------ src/components/UnderConstruction.js | 3 +- src/components/database/cards.js | 35 ++++++++++ src/components/database/portal.js | 85 +++++++++++++++++++++++ webpack.config.babel.js | 4 ++ 11 files changed, 187 insertions(+), 64 deletions(-) create mode 100644 src/components/database/cards.js create mode 100644 src/components/database/portal.js diff --git a/chaotic-portal.sublime-project b/chaotic-portal.sublime-project index bc56dfd..6c34aae 100644 --- a/chaotic-portal.sublime-project +++ b/chaotic-portal.sublime-project @@ -1,10 +1,11 @@ { "folders": - [ - { - "path": "." - } - ], + [ + { + "path": ".", + "folder_exclude_patterns": ["build", "node_modules"] + } + ], "syntax_override": { "\\.js$": diff --git a/package.json b/package.json index e9d27a5..9cbaffe 100644 --- a/package.json +++ b/package.json @@ -13,24 +13,28 @@ "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", + "mobx": "^3.3.1", + "mobx-react": "^4.3.3", + "prop-types": "^15.6.0", + "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", "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-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" } diff --git a/src/Base.js b/src/Base.js index 4bafd28..2e06e36 100644 --- a/src/Base.js +++ b/src/Base.js @@ -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'; diff --git a/src/components/ExampleComponent.js b/src/components/ExampleComponent.js index f08ddda..042119a 100644 --- a/src/components/ExampleComponent.js +++ b/src/components/ExampleComponent.js @@ -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'; diff --git a/src/components/ExampleTwoDeepComponent.js b/src/components/ExampleTwoDeepComponent.js index 0646d5c..379cf17 100644 --- a/src/components/ExampleTwoDeepComponent.js +++ b/src/components/ExampleTwoDeepComponent.js @@ -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'; diff --git a/src/components/PageNotFound.js b/src/components/PageNotFound.js index 8a4d3a2..5d13f85 100644 --- a/src/components/PageNotFound.js +++ b/src/components/PageNotFound.js @@ -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 = { diff --git a/src/components/SpreadsheetData.js b/src/components/SpreadsheetData.js index 0fa569d..1688776 100644 --- a/src/components/SpreadsheetData.js +++ b/src/components/SpreadsheetData.js @@ -1,39 +1,44 @@ -import React from 'react'; import 'whatwg-fetch'; +import CardsDB from './database/cards'; +import PortalDB from './database/portal'; -class URLS { +class API { 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="; } - static path(spreadsheetID) { - return URLS.base_url + spreadsheetID + URLS.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; - }); - }); - } - // Singleton instance = null; static getInstance() { - if (!URLS.instance) { URLS.instance = new URLS(); } - return URLS.instance; + if (!API.instance) { API.instance = new API(); } + return API.instance; + } + + static path(spreadsheetID) { + return API.base_url + spreadsheetID + API.data_format; + } + + constructor() { + var self = this; + + // This sets up urls and kicks off db + this.urls = {}; + this.getSpreadsheet(API.path(API.base_spreadsheet), function(data) { + if (data == null) return; + 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] = API.path(d.gsx$url.$t); + }); + self.setupDB(); + }); } getSpreadsheet(spreadsheet, callback) { fetch(spreadsheet) .then(function(response) { + // console.log(response); return response.json(); }).then(function(json) { return callback(json.feed.entry); @@ -43,31 +48,15 @@ class URLS { }); } - /* Creatures */ - /* TODO remove legacy getters when introducing state management*/ - get Creatures_Card_Data() { - return URLS.path("1fUFYhG1NLLkSTzrdbevm6ZMKNP6xLiKUZvM1sY10pVI"); + setupDB() { + try { + this.portal = new PortalDB(this); + this.cards = new CardsDB(this); + } + 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(); diff --git a/src/components/UnderConstruction.js b/src/components/UnderConstruction.js index f774de7..e154f1f 100644 --- a/src/components/UnderConstruction.js +++ b/src/components/UnderConstruction.js @@ -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 = { diff --git a/src/components/database/cards.js b/src/components/database/cards.js new file mode 100644 index 0000000..42425ae --- /dev/null +++ b/src/components/database/cards.js @@ -0,0 +1,35 @@ +export default class CardsDB { + constructor(API) { + // this.api = API; + // 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; + } + + setupCreatures(spreadsheet) { + this.getSpreadsheet(spreadsheet, function(json) { + + }); + } + + setupMugic(spreadsheet) { + this.getSpreadsheet(spreadsheet, function(json) { + + }); + } + + setupBattleGear(spreadsheet) { + this.getSpreadsheet(spreadsheet, function(json) { + + }); + } + + setupLocations(spreadsheet) { + this.getSpreadsheet(spreadsheet, function(json) { + + }); + } +} diff --git a/src/components/database/portal.js b/src/components/database/portal.js new file mode 100644 index 0000000..e6405aa --- /dev/null +++ b/src/components/database/portal.js @@ -0,0 +1,85 @@ +import loki from 'lokijs'; + +export default class PortalDB { + constructor(API) { + this.api = API; + this.setupDB(); + this.setupCreatures("Overworld"); + } + + setupDB() { + var self = this; + // let db = new loki("chaotic_portal.db", { autosave: true, autoload: true, autoloadCallback: databaseInitialize, autosaveInterval: 4000, persistenceMethod: 'localStorage' }); + let db = new loki("chaotic_portal.db"); // ignoring persistence for now + 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; + + // function 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, function(data) { + data.map(function(item) { + // delete item.category; + // delete item.id; + // delete item.updated; + // delete item.content; + // delete item.link; + // delete item.title; + item.name = item.gsx$name.$t; + return item; + }); + callback(data); + }); + } + + setupAttacks() { + + } + + setupBattleGear() { + + } + + setupCreatures(tribe) { + // console.log(this); + var self = this; + this.setup(this.api.urls.Creatures[tribe], function(data) { + self.creatures.insert(data); + }); + } + + setupLocations() { + + } + + setupMugic(tribe) { + + } +} diff --git a/webpack.config.babel.js b/webpack.config.babel.js index 578dfe0..0b45362 100644 --- a/webpack.config.babel.js +++ b/webpack.config.babel.js @@ -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'), From 4934fdd9c22de03249e94d225086536b57bd34da Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 11 Nov 2017 21:02:18 -0500 Subject: [PATCH 2/3] close #12 close #3 --- .babelrc | 3 +- package.json | 5 +- src/components/AppHelper.js | 39 ------- src/components/SpreadsheetData.js | 28 +++-- src/components/database/portal.js | 87 +++++++------- src/components/portal/Single/Creature.js | 140 ++++++++++++++++------- src/index.js | 7 ++ 7 files changed, 172 insertions(+), 137 deletions(-) delete mode 100644 src/components/AppHelper.js diff --git a/.babelrc b/.babelrc index 562a5e3..64fe89c 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,4 @@ { - "presets": ["es2015", "react", "stage-1"] + "presets": ["es2015", "react", "stage-1"], + "plugins": ["transform-decorators-legacy"] } diff --git a/package.json b/package.json index 9cbaffe..177aea5 100644 --- a/package.json +++ b/package.json @@ -13,20 +13,23 @@ "author": "Danude Sandstorm", "license": "MIT", "dependencies": { + "lokijs": "^1.5.1", + "prop-types": "^15.6.0", "mobx": "^3.3.1", "mobx-react": "^4.3.3", - "prop-types": "^15.6.0", "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": "^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", diff --git a/src/components/AppHelper.js b/src/components/AppHelper.js deleted file mode 100644 index 28e07c4..0000000 --- a/src/components/AppHelper.js +++ /dev/null @@ -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; -} diff --git a/src/components/SpreadsheetData.js b/src/components/SpreadsheetData.js index 1688776..2eec047 100644 --- a/src/components/SpreadsheetData.js +++ b/src/components/SpreadsheetData.js @@ -1,8 +1,14 @@ import 'whatwg-fetch'; import CardsDB from './database/cards'; import PortalDB from './database/portal'; +import {observable} from "mobx"; class API { + @observable portal = null; + @observable cards = null; + @observable urls = null; + @observable instance = null; + 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 @@ -10,10 +16,9 @@ class API { get base_image() { return "https://drive.google.com/uc?id="; } // Singleton - instance = null; static getInstance() { - if (!API.instance) { API.instance = new API(); } - return API.instance; + if (!this.instance) { this.instance = new API(); } + return this.instance; } static path(spreadsheetID) { @@ -21,17 +26,16 @@ class API { } constructor() { - var self = this; - // This sets up urls and kicks off db - this.urls = {}; - this.getSpreadsheet(API.path(API.base_spreadsheet), function(data) { + let urls = {}; + this.getSpreadsheet(API.path(API.base_spreadsheet), (data) => { if (data == null) return; - 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] = API.path(d.gsx$url.$t); + 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); }); - self.setupDB(); + this.urls = urls; + this.setupDB(); }); } @@ -60,3 +64,5 @@ class API { } export default API.getInstance(); + +// export default new API(); diff --git a/src/components/database/portal.js b/src/components/database/portal.js index e6405aa..5ec5142 100644 --- a/src/components/database/portal.js +++ b/src/components/database/portal.js @@ -1,61 +1,63 @@ import loki from 'lokijs'; +import {observable, autorun} from "mobx"; export default class PortalDB { + @observable built = []; // Keeps track of what collections have been populated + constructor(API) { this.api = API; - this.setupDB(); - this.setupCreatures("Overworld"); - } - - setupDB() { - var self = this; - // let db = new loki("chaotic_portal.db", { autosave: true, autoload: true, autoloadCallback: databaseInitialize, autosaveInterval: 4000, persistenceMethod: 'localStorage' }); - let db = new loki("chaotic_portal.db"); // ignoring persistence for now + // 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; + } - // function databaseInitialize() { - // var entries; - // if ((entries = db.getCollection("attacks")) === null) - // entries = db.addCollection("attacks"); - // self.attacks = entries; + setupDB() { + var self = this; + let db = new loki("chaotic_portal.db", { autosave: true, autoload: true, autoloadCallback: databaseInitialize, autosaveInterval: 4000, persistenceMethod: 'localStorage' }); + this.db = db; - // if ((entries = db.getCollection("battlegear")) === null) - // entries = db.addCollection("battlegear"); - // self.battlegear = entries; + let databaseInitialize = () => { + var entries; + if ((entries = db.getCollection("attacks")) === null) + entries = db.addCollection("attacks"); + self.attacks = 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("battlegear")) === null) + entries = db.addCollection("battlegear"); + self.battlegear = entries; - // if ((entries = db.getCollection("locations")) === null) - // entries = db.addCollection("locations"); - // self.locations = 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("mugic")) === null) - // entries = db.addCollection("mugic"); - // self.mugic = entries; - // } + 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, function(data) { - data.map(function(item) { - // delete item.category; - // delete item.id; - // delete item.updated; - // delete item.content; - // delete item.link; - // delete item.title; - item.name = item.gsx$name.$t; - return item; - }); - callback(data); + 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; + })); }); } @@ -68,10 +70,9 @@ export default class PortalDB { } setupCreatures(tribe) { - // console.log(this); - var self = this; - this.setup(this.api.urls.Creatures[tribe], function(data) { - self.creatures.insert(data); + this.setup(this.api.urls.Creatures[tribe], (data) => { + this.creatures.insert(data); + this.built.push("creatures_"+tribe); }); } diff --git a/src/components/portal/Single/Creature.js b/src/components/portal/Single/Creature.js index 5c58ffa..39972b6 100644 --- a/src/components/portal/Single/Creature.js +++ b/src/components/portal/Single/Creature.js @@ -6,45 +6,25 @@ 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("/"); - if (path[path.length-1] == "") path.pop(); // Remove trailing backslash - // Path too long - if ( path.length !== 5 ) { - return; - } - - //Handle both url layouts - let tribe = (() => { - 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; + var creature = API.portal.creatures.findOne(name); + if (creature) self.setState({"creature": creature}); + else self.setState({creature: "n/a"}); + console.log(creature); API.getSpreadsheet(API.Creatures[tribe], (data) => { data.map((item, i) => { if (item.title.$t == name) @@ -67,28 +47,104 @@ export default class SingleCreature extends React.Component { } render() { - var self = this; + const store = API; - // Get spreadsheet data based on tribe/name - if (!(API.Creatures).hasOwnProperty(this.state.tribe)) { - return( - - //return(browserHistory.push('/PageNotFound')); - ); + 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(); } - // creature is the object to be used in the jsx - var creature = this.state.creature; - var card_data = this.state.card_data; + //Handle both url layouts + let tribe = (() => { + if (path[2] === "Creatures") return path[3]; + if (path[3] === "Creatures") return path[2]; + })(); - // TODO separate loading of card_data - if (creature == "n/a" || card_data == "n/a") return( - - ); + if (store.urls === null || + store.portal === null || + store.cards === null) { + return (Loading...); + } - if (creature == null || card_data == null) return( - Loading... + // Todo this isn't needed for now (handled by routes) + // if (!store.urls.Creatures.hasOwnProperty(tribe)) { + // return (Invalid Tribe: {tribe}); + // } + + if (!store.portal.built.includes("creatures_"+tribe)) { + store.portal.setupCreatures(tribe); + return (Loading...); + } + // TODO load card data + + const creature = store.portal.creatures.findOne({'gsx$name': path[4]}); + console.log(creature); + if (!creature) { + return(); + } + + const locations = creature.gsx$location.split(/[,]+\s*/).map((item, i) => { + return

{item}

; + }); + + const battlegear = creature.gsx$battlegear.split(/[,]+\s*/).map((item, i) => { + return

{item}

; + }); + + return ( +
+ +

{creature.gsx$name}

+ +
+
+ Appearance:
+ {creature.gsx$appearance} +
+
+
+ Background:
+ {creature.gsx$background} +
+
+
+ Details:
+ {creature.gsx$details} +
+
+
+ Favorite Battlegear(s):
+ {battlegear} +
+
+
+ Favorite Location(s):
+ {locations} +
+
+
+ Height (ft):
+ {creature.gsx$height} +
+
+
+ Special Abilities:
+ {creature.gsx$specialabilities} +
+
+
+ Weight (lb):
+ {creature.gsx$weight} +
+
); + } + + fakerender() { + var self = this; const elements = card_data.gsx$elements.$t.split(/[ ,]+/).map((item, i) => { return {item}; diff --git a/src/index.js b/src/index.js index 56d20d9..edcd011 100644 --- a/src/index.js +++ b/src/index.js @@ -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 */} + + {/* Portal */} @@ -168,6 +173,8 @@ const routes = ( + + From c57760bb114f920a49ab62bab47e60f6dec3d9cb Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 11 Nov 2017 22:07:16 -0500 Subject: [PATCH 3/3] single creature updated stubbed other types --- src/components/CollectionDB.js | 86 +++++++++++++ src/components/SpreadsheetData.js | 9 +- src/components/database/cards.js | 35 ------ src/components/database/portal.js | 86 ------------- src/components/portal/Category/Creatures.js | 54 ++------ src/components/portal/Category/Mugic.js | 27 ++-- src/components/portal/Single/Creature.js | 129 ++++---------------- 7 files changed, 134 insertions(+), 292 deletions(-) create mode 100644 src/components/CollectionDB.js delete mode 100644 src/components/database/cards.js delete mode 100644 src/components/database/portal.js diff --git a/src/components/CollectionDB.js b/src/components/CollectionDB.js new file mode 100644 index 0000000..8ab24be --- /dev/null +++ b/src/components/CollectionDB.js @@ -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) { + + } +} diff --git a/src/components/SpreadsheetData.js b/src/components/SpreadsheetData.js index 2eec047..eebf412 100644 --- a/src/components/SpreadsheetData.js +++ b/src/components/SpreadsheetData.js @@ -1,13 +1,12 @@ import 'whatwg-fetch'; -import CardsDB from './database/cards'; -import PortalDB from './database/portal'; +import CollectionDB from './CollectionDB'; import {observable} from "mobx"; class API { @observable portal = null; @observable cards = null; @observable urls = null; - @observable instance = null; + instance = null; static base_url = "https://spreadsheets.google.com/feeds/list/"; static data_format = "/od6/public/values?alt=json"; @@ -54,8 +53,8 @@ class API { setupDB() { try { - this.portal = new PortalDB(this); - this.cards = new CardsDB(this); + this.portal = new CollectionDB(this, "portal"); + this.cards = new CollectionDB(this, "cards"); } catch (err) { console.log('setting up database failed', err); diff --git a/src/components/database/cards.js b/src/components/database/cards.js deleted file mode 100644 index 42425ae..0000000 --- a/src/components/database/cards.js +++ /dev/null @@ -1,35 +0,0 @@ -export default class CardsDB { - constructor(API) { - // this.api = API; - // 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; - } - - setupCreatures(spreadsheet) { - this.getSpreadsheet(spreadsheet, function(json) { - - }); - } - - setupMugic(spreadsheet) { - this.getSpreadsheet(spreadsheet, function(json) { - - }); - } - - setupBattleGear(spreadsheet) { - this.getSpreadsheet(spreadsheet, function(json) { - - }); - } - - setupLocations(spreadsheet) { - this.getSpreadsheet(spreadsheet, function(json) { - - }); - } -} diff --git a/src/components/database/portal.js b/src/components/database/portal.js deleted file mode 100644 index 5ec5142..0000000 --- a/src/components/database/portal.js +++ /dev/null @@ -1,86 +0,0 @@ -import loki from 'lokijs'; -import {observable, autorun} from "mobx"; - -export default class PortalDB { - @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) { - this.setup(this.api.urls.Creatures[tribe], (data) => { - this.creatures.insert(data); - this.built.push("creatures_"+tribe); - }); - } - - setupLocations() { - - } - - setupMugic(tribe) { - - } -} diff --git a/src/components/portal/Category/Creatures.js b/src/components/portal/Category/Creatures.js index f51e104..b7ea23e 100644 --- a/src/components/portal/Category/Creatures.js +++ b/src/components/portal/Category/Creatures.js @@ -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 (
{this.props.children}
); + } + return ( + + ); + } + + fakerender() { if (this.props.children) { return (
{this.props.children}
); } diff --git a/src/components/portal/Category/Mugic.js b/src/components/portal/Category/Mugic.js index e043748..3585e9b 100644 --- a/src/components/portal/Category/Mugic.js +++ b/src/components/portal/Category/Mugic.js @@ -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 (
{this.props.children}
); + } + return ( + + ); + } + + fakerender() { if (this.props.children) { return (
{this.props.children}
); } diff --git a/src/components/portal/Single/Creature.js b/src/components/portal/Single/Creature.js index 39972b6..5172fac 100644 --- a/src/components/portal/Single/Creature.js +++ b/src/components/portal/Single/Creature.js @@ -1,9 +1,7 @@ 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'; @@ -15,37 +13,6 @@ export default class SingleCreature extends React.Component { // /portal/Creatures/{Tribe}/{Name} // /portal/{Tribe}/Creatures/{Name} // The first / gets counted - getData(props) { - - - var name = decodeURIComponent(path[4]); - - var self = this; - var creature = API.portal.creatures.findOne(name); - if (creature) self.setState({"creature": creature}); - else self.setState({creature: "n/a"}); - console.log(creature); - 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() { const store = API; @@ -74,14 +41,18 @@ export default class SingleCreature extends React.Component { // return (Invalid Tribe: {tribe}); // } + if (!store.cards.built.includes("creatures_Cards")) { + store.cards.setupCreatures("Cards"); + return (Loading...); + } + if (!store.portal.built.includes("creatures_"+tribe)) { store.portal.setupCreatures(tribe); return (Loading...); } - // TODO load card data const creature = store.portal.creatures.findOne({'gsx$name': path[4]}); - console.log(creature); + const card_data = store.cards.creatures.findOne({'gsx$name': path[4]}); if (!creature) { return(); } @@ -94,9 +65,12 @@ export default class SingleCreature extends React.Component { return

{item}

; }); + const elements = card_data.gsx$elements.split(/[ ,]+/).map((item, i) => { + return {item}; + }); + return (
-

{creature.gsx$name}


@@ -139,113 +113,60 @@ export default class SingleCreature extends React.Component { Weight (lb):
{creature.gsx$weight}
- - ); - } - - fakerender() { - var self = this; - - const elements = card_data.gsx$elements.$t.split(/[ ,]+/).map((item, i) => { - return {item}; - }); - - const locations = creature.gsx$location.$t.split(/[,]+\s*/).map((item, i) => { - return

{item}

; - }); - - const battlegear = creature.gsx$battlegear.$t.split(/[,]+\s*/).map((item, i) => { - return

{item}

; - }); - - return( -
-

{creature.gsx$name.$t}

- -
-
- Appearance:
- {creature.gsx$appearance.$t} -
-
-
- Background:
- {creature.gsx$background.$t} -
-
-
- Details:
- {creature.gsx$details.$t} -
-
-
- Favorite Battlegear(s):
- {battlegear} -
-
-
- Favorite Location(s):
- {locations} -
-
-
- Height (ft):
- {creature.gsx$height.$t} -

Special Abilities:
- {creature.gsx$specialabilities.$t} + {creature.gsx$specialabilities}

Weight (lb):
- {creature.gsx$weight.$t} + {creature.gsx$weight}

Card ID: - {card_data.gsx$cardid.$t} + {card_data.gsx$cardid}

Set: - {card_data.gsx$set.$t} + {card_data.gsx$set}

Rarity: - {card_data.gsx$rarity.$t} + {card_data.gsx$rarity}

- Tribe: {this.state.tribe} - + Tribe: {tribe} +

Ability:
- {card_data.gsx$ability.$t} + {card_data.gsx$ability}

Courage: - {card_data.gsx$courage.$t} + {card_data.gsx$courage}

Power: - {card_data.gsx$power.$t} + {card_data.gsx$power}

Speed: - {card_data.gsx$speed.$t} + {card_data.gsx$speed}

Wisdom: - {card_data.gsx$wisdom.$t} + {card_data.gsx$wisdom}

@@ -254,17 +175,17 @@ export default class SingleCreature extends React.Component {
Energy: - {card_data.gsx$energy.$t} + {card_data.gsx$energy}

Flavortext:
- {card_data.gsx$flavortext.$t} + {card_data.gsx$flavortext}

Mugic Ability: - {card_data.gsx$mugicability.$t} + {card_data.gsx$mugicability}
);