updated collection search

This commit is contained in:
Daniel 2019-03-26 01:50:10 -04:00
parent be9aea9bfb
commit 35d69ac19a
9 changed files with 677 additions and 1136 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,513 +0,0 @@
@media only screen and (min-width: 975px) {
.pack {
max-width: 70%; } }
/* Desktop */
.packsim input[type=number]::-webkit-inner-spin-button,
.packsim input[type=number]::-webkit-outer-spin-button {
opacity: 1; }
.pack {
height: 100%;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
margin: auto;
/* Energy */
/* Energy */ }
.pack .card {
width: 150px;
height: 210px;
background-size: cover;
box-sizing: content-box;
margin: 5px;
-webkit-transition: -webkit-transform 1s,opacity 1s,background 1s,width 1s,height 1s,font-size 1s,top 1s,left 1s;
-webkit-border-radius: 5px;
-o-transition-property: width,height,-o-transform,background,font-size,opacity,top,left;
-o-transition-duration: 1s,1s,1s,1s,1s,1s,1s,1s;
-moz-transition-property: width,height,-o-transform,background,font-size,opacity,top,left;
-moz-transition-duration: 1s,1s,1s,1s,1s,1s,1s,1s;
transition-property: width,height,transform,background,font-size,opacity,top,left;
transition-duration: 1s,1s,1s,1s,1s,1s,1s,1s; }
.pack .card:hover {
width: 250px;
height: 350px; }
.pack .stats {
height: 100%;
width: 100%;
text-align: left; }
.pack .stats span {
position: relative;
color: black;
display: block;
left: 10px;
font-size: 12px; }
.pack .stats span:nth-of-type(1) {
top: 130px; }
.pack .stats span:nth-of-type(2) {
top: 128px; }
.pack .stats span:nth-of-type(3) {
top: 126px; }
.pack .stats span:nth-of-type(4) {
top: 124px; }
.pack .stats span:nth-of-type(5) {
text-align: right;
top: 125px;
left: -11px;
font-size: 14px; }
.pack .card:hover .stats span {
left: 20px;
font-size: 14px;
font-weight: bold; }
.pack .card:hover .stats span:nth-of-type(1) {
top: 220px; }
.pack .card:hover .stats span:nth-of-type(2) {
top: 229px; }
.pack .card:hover .stats span:nth-of-type(3) {
top: 237px; }
.pack .card:hover .stats span:nth-of-type(4) {
top: 245px; }
.pack .card:hover .stats span:nth-of-type(5) {
text-align: right;
top: 258px;
left: -21px;
font-size: 20px; }
.icon14 {
height: 14px;
padding-bottom: 2px; }
.icon16 {
height: 16px; }
.icon20 {
height: 20px; }
.icon24 {
height: 24px; }
.bigger {
font-size: 14px; }
.name {
-webkit-user-select: all;
-moz-user-select: all;
-ms-user-select: all;
user-select: all; }
.name .subname::before {
content: "\A ";
white-space: pre; }
.name .subname {
font-size: 13px;
padding-bottom: 4px;
display: inherit; }
#player {
text-align: center; }
@media only screen and (min-width: 975px) {
.collection > .left {
float: left;
width: 30%; }
.collection > .right {
float: right;
width: 70%; }
.card {
text-align: left;
display: flex;
border: 1px solid #AEAEAE; }
.card .left,
.card .right,
.card .stats {
padding-top: 2px; }
.card .left {
vertical-align: text-top;
float: left;
width: 210px;
padding-left: 4px; }
.card .right {
float: left;
width: calc(100% - (100px + 4px + 4px + 4px + 210px));
border-left: 2px solid #AEAEAE;
padding-left: 4px;
padding-right: 4px;
padding-bottom: 6px;
white-space: pre-line; }
.creature .right {
width: calc(100% - (100px + 4px + 4px + 4px + 210px + 40px + 4px)); }
.creature .stats {
vertical-align: text-top;
float: left;
text-align: right;
width: 40px;
padding-right: 4px; }
.SearchForm {
text-align: left; }
.brainwashed {
background-color: #dcdddf;
color: black !important; }
.flavortext,
.chieftain {
font-style: italic; }
.disciplines input {
width: 30px;
height: 14px;
text-align: center;
margin-top: 2px; }
.mull input {
vertical-align: middle; }
.mcbp input {
width: 24px;
height: 14px;
padding: unset;
text-align: center;
margin-top: 2px; }
.and {
vertical-align: text-bottom;
padding: 0 4px; } }
/* desktop */
.card .icon14, .card .icon16,
.card .icon20, .card .icon24 {
vertical-align: middle; }
.thumb {
width: 100px;
height: 98px; }
.card .thumb {
float: left; }
.Collapsible {
margin-bottom: 10px;
width: 250px; }
.Collapsible__trigger {
background-color: #333;
display: block;
position: relative;
padding-top: 5px;
padding-bottom: 5px;
text-indent: 5px; }
.Collapsible__trigger:hover {
background-color: red; }
.Collapsible__trigger:after {
content: '^';
position: absolute;
right: 10px;
top: 10px;
display: block;
transition: transform 400ms; }
.Collapsible__trigger.is-open:after {
transform: rotateZ(180deg);
right: 5px;
top: 5px; }
.Collapsible__trigger.is-disabled {
opacity: 0.5;
background-color: grey; }
.left {
position: relative; }
.card_img {
position: absolute;
width: 100%;
left: -10px;
z-index: 2; }
.card_img .hidden {
display: none;
max-height: 0; }
.card_img img {
max-width: 250px;
max-height: 350px; }
.entries {
text-align: left; }
.list-nav-top {
display: flex; }
.list-nav-top .ext-button {
float: right;
margin: auto 0 0 auto; }
.extended .fullcard {
max-width: 250px;
max-height: 350px; }
.portal {
/* portal css */
/*.navbar .dropdown-content a:hover {
background-color: #f1f1f1
}*/
/*end portal css*/ }
.portal .navbar h1 {
font-size: 16px; }
.portal .navbar ul {
list-style-type: none;
margin: 0;
padding: 0;
overflow: hidden;
background-color: #333; }
.portal .navbar li {
float: left; }
.portal .navbar li a, .portal .navbar .dropbtn {
display: inline-block;
color: white;
text-align: center;
padding: 14px 16px;
text-decoration: none; }
.portal .navbar li a:hover, .portal .navbar .dropdown:hover .dropbtn {
background-color: red; }
.portal .navbar li.dropdown {
display: inline-block; }
.portal .navbar .dropdown-content {
display: none;
position: absolute;
/*background-color: #f9f9f9;*/
background-color: #333;
min-width: 140px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1; }
.portal .navbar .dropdown-content a {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
text-align: left; }
.portal .navbar .dropdown:hover .dropdown-content {
display: block; }
.portal .magnifying-glass {
cursor: pointer;
transition: color .2s;
z-index: 1;
vertical-align: middle;
fill: currentColor;
height: 18px;
min-width: 18px;
width: 18px; }
.portal .search .results div {
padding-bottom: 10px; }
.portal .search .results a {
font-size: 16px;
line-height: 20px; }
.portal .entry {
font-size: 1.2em;
/* height is 118px */
/* The Modal (background) */
/* Modal Content (image) */
/* Caption of Modal Image */
/* Add Animation */
/* The Close Button */
/*end entry*/ }
.portal .entry .title {
font-weight: bold;
font-size: 16px; }
.portal .entry .left {
float: left;
width: 100px; }
.portal .entry .right {
float: right;
width: 86%; }
.portal .entry .left .title {
text-align: left;
padding-bottom: 10px; }
.portal .entry .icon14, .portal .entry .icon16,
.portal .entry .icon20, .portal .entry .icon24 {
vertical-align: middle; }
.portal .entry .entry_content {
min-height: 550px;
height: calc(100vh - 300px);
overflow-y: auto;
width: 100%;
position: relative; }
.portal .entry .entry_content .entry_splash {
padding-bottom: 4px; }
.portal .entry .entry_content .entry_splash img {
max-width: 100%; }
.portal .entry .entry_content .entry_splash .arrow {
position: absolute;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
width: 100%;
top: 95%; }
.portal .entry .entry_content .entry_body {
position: relative;
max-width: 100%;
padding-bottom: 4px;
display: flex;
flex-wrap: wrap; }
.portal .entry .entry_content .entry_body hr {
margin: 0px; }
.portal .entry .entry_content .entry_body .title {
min-width: 100%; }
.portal .entry .entry_content .entry_body .title hr {
margin-top: 8px; }
.portal .entry .entry_content .entry_body .column > div,
.portal .entry .entry_content .entry_body .nocolumn > div {
padding-left: 8px;
padding-right: 8px;
padding-top: 8px;
padding-bottom: 8px; }
.portal .entry .entry_content .entry_body .column:nth-child(2) {
flex-grow: 1;
text-align: left;
min-width: 0;
width: 30%; }
.portal .entry .entry_content .entry_body .column:last-child {
flex-grow: 2;
min-width: 0;
flex: 60%;
border-left: 1px solid white; }
.portal .entry .entry_content .entry_body .ability {
white-space: pre-line;
word-wrap: break-all; }
.portal .entry .entry_content::-webkit-scrollbar {
width: 1px; }
.portal .entry .cat_title {
text-align: left;
background-color: #1a1a1a;
font-weight: bold;
font-size: 16px;
padding-top: 1px;
padding-left: 4px; }
.portal .entry .entry_nav {
background-color: #1a1a1a;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap; }
.portal .entry .entry_nav > div {
display: inline-block; }
.portal .entry .entry_nav > div img {
margin-right: 3px;
margin-left: 3px; }
.portal .entry .modal {
position: fixed;
/* Stay in place */
z-index: 10;
/* Sit on top */
padding-top: 50px;
left: 0;
top: 0;
width: 100%;
/* Full width */
height: 100%;
/* Full height */
overflow: auto;
/* Enable scroll if needed */
background-color: black;
/* Fallback color */
background-color: rgba(0, 0, 0, 0.9);
/* Black w/ opacity */ }
.portal .entry .modal.hidden {
display: none; }
.portal .entry .modal-content {
margin: auto;
display: block;
max-height: calc(100vh - 100px);
max-width: 90vw; }
.portal .entry .caption {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
text-align: center;
color: #ccc;
padding: 10px 0;
height: 150px; }
.portal .entry .modal-content, .portal .entry #caption {
-webkit-animation-name: zoom;
-webkit-animation-duration: 0.6s;
animation-name: zoom;
animation-duration: 0.6s; }
@-webkit-keyframes zoom {
from {
-webkit-transform: scale(0); }
to {
-webkit-transform: scale(1); } }
@keyframes zoom {
from {
transform: scale(0); }
to {
transform: scale(1); } }
.portal .entry .close {
position: fixed;
top: 35px;
right: 35px;
color: #f1f1f1;
font-size: 40px;
font-weight: bold;
transition: 0.3s; }
.portal .entry .close:hover,
.portal .entry .close:focus {
color: #bbb;
text-decoration: none;
cursor: pointer; }
.lore {
text-align: left;
padding-left: 10%;
padding-right: 10%; }
.lore .title {
margin-top: 6px;
text-align: center;
font-weight: bold;
font-size: 18px; }
.lore div {
margin: 0 0 6px;
line-height: 22px !important; }
.donate {
margin-bottom: 6px; }
.donate form a {
border-bottom: none; }
/* With Love */
@-webkit-keyframes love {
to {
-webkit-transform: scale(1.1); } }
@-moz-keyframes love {
to {
-moz-transform: scale(1.1); } }
@keyframes love {
to {
transform: scale(1.1); } }
.with-love {
color: #333;
/*display: inline-block;*/ }
.with-love span,
.with-love div {
font-size: 14px !important;
line-height: 18px !important; }
.with-love div {
padding-bottom: 4px; }
.with-love .heart {
font-size: 1.4em;
color: #ff79c6;
-webkit-transform: scale(0.9);
-moz-transform: scale(0.9);
transform: scale(0.9);
-webkit-animation: love .5s infinite linear alternate-reverse;
-moz-animation: love .5s infinite linear alternate-reverse;
animation: love .5s infinite linear alternate-reverse; }
.with-love a {
text-decoration: none;
border-bottom: 1px dotted; }

View File

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Chaotic Backup</title>
<meta name="description" content="Chaotic Backup">
<link rel="stylesheet" type="text/css" href="/build/style.css">
<link rel="stylesheet" type="text/css" href="/build/main.css">
<link rel="stylesheet" type="text/css" href="/src/css/legacy.css">
<style>
html, body, div, span, a, p, ul, li, h1 {

View File

@ -1,606 +0,0 @@
import React from 'react';
import {observable} from "mobx";
import {observer, inject} from 'mobx-react';
import loki from 'lokijs';
import Collapsible from 'react-collapsible';
import API from '../SpreadsheetData';
import {Loading} from '../Snippets';
@inject((stores, props, context) => props) @observer
export default class SearchCollection extends React.Component {
@observable loaded = false;
@observable input;
list = ["sets", "types", "rarity", "tribes", "elements", "mull", "gender"];
constructor(props) {
super(props);
this.filter = new loki("filter.db");
// Binding for keeping scope with dom functions
this.search = this.search.bind(this);
this.handleChange = this.handleChange.bind(this);
this.reset = this.reset.bind(this);
this.props.handleContent([{'text': 'Loading...'}]);
this.cleanInput();
this.parseQuery();
}
cleanInput = () => {
let input = {
name: "",
text: "",
subtypes: "",
past: false,
mirage: false,
sets: {},
types: {attack: false, battlegear: false, creature: false, location: false, mugic: false},
rarity: {common: false, uncommon: false, rare: false, 'super rare': false, 'ultra rare': false, promo: false},
tribes: {danian: false, 'm\'arrillian': false, 'mipedian': false, overworld: false, underworld: false, generic: false},
elements: {fire: false, air: false, earth: false, water: false, none: false, and: false},
disciplines: {courage: '', power: '', wisdom: '', speed: ''},
energy: {min: '', max: ''},
mcbp: {min: '', max: ''},
mull: {unique: false, loyal: false, legendary: false, mixed: false},
gender: {ambiguous: false, female: false, male: false}
};
for (const key in API.sets) input.sets[key.toLowerCase()] = false;
this.input = input;
}
parseQuery = () => {
const queryString = this.props.location.search.toLowerCase();
let query = {};
let pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
for (let i = 0; i < pairs.length; i++) {
let pair = pairs[i].split('=');
query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
}
// query -> input
this.list.forEach((d) => {
if (query[d]) {
query[d].split(',').map(item => {
this.input[d][item] = true;
});
}
});
if (query.hasOwnProperty('past')) this.input.past = true;
if (query.hasOwnProperty('mirage')) this.input.mirage = true;
if (query.hasOwnProperty('name')) this.input.name = query.name;
if (query.hasOwnProperty('text')) this.input.text = query.text;
if (query.hasOwnProperty('subtypes')) this.input.subtypes = query.subtypes;
if (query.hasOwnProperty('courage')) this.input.disciplines.courage = query.courage;
if (query.hasOwnProperty('power')) this.input.disciplines.power = query.power;
if (query.hasOwnProperty('wisdom')) this.input.disciplines.wisdom = query.wisdom;
if (query.hasOwnProperty('speed')) this.input.disciplines.speed = query.speed;
if (query.hasOwnProperty('energy')) {
let q = query.energy.split(',');
if (q[0] >= 0) this.input.energy.min = q[0];
if (q[1] >= 0) this.input.energy.max = q[1];
}
if (query.hasOwnProperty('mcbp')) {
let q = query.mcbp.split(',');
if (q[0] >= 0) this.input.mcbp.min = q[0];
if (q[1] >= 0) this.input.mcbp.max = q[1];
}
}
async updateQuery() {
let queryString = "";
let update = (query) => {
let temp = "";
Object.keys(this.input[query]).forEach((item) => {
if (this.input[query][item] == true) temp += item + ",";
});
if (temp.length > 0) return query + "=" + temp.replace(/\,$/, '&');
else return "";
}
this.list.forEach(item => queryString += update(item));
if (this.input.past) queryString += "past&";
if (this.input.mirage) queryString += "mirage&";
if (this.input.name) queryString += "name=" + encodeURIComponent(this.input.name) + "&";
if (this.input.text) queryString += "text=" + encodeURIComponent(this.input.text) + "&";
if (this.input.subtypes) queryString += "subtypes=" + encodeURIComponent(this.input.subtypes) + "&";
if (this.input.disciplines.courage > 0) queryString += "courage=" + this.input.disciplines.courage + "&";
if (this.input.disciplines.power > 0) queryString += "power=" + this.input.disciplines.power + "&";
if (this.input.disciplines.wisdom > 0) queryString += "wisdom=" + this.input.disciplines.wisdom + "&";
if (this.input.disciplines.speed > 0) queryString += "speed=" + this.input.disciplines.speed + "&";
if (this.input.energy.min != "" || this.input.energy.max != "") {
queryString += "energy=";
if (this.input.energy.min != "" && this.input.energy.min >= 0) queryString += this.input.energy.min;
queryString += ",";
if (this.input.energy.max != "" && this.input.energy.max >= 0) queryString += this.input.energy.max;
queryString += "&";
}
if (this.input.mcbp.min != "" || this.input.mcbp.max != "") {
queryString += "mcbp=";
if (this.input.mcbp.min != "" && this.input.mcbp.min >= 0) queryString += this.input.mcbp.min;
queryString += ",";
if (this.input.mcbp.max != "" && this.input.mcbp.max >= 0) queryString += this.input.mcbp.max;
queryString += "&";
}
// Strip trailing &
queryString = queryString.replace(/\&$/, '');
// Push to URL
this.props.history.push('/collection/?'+(queryString));
}
render() {
if (this.loaded == false) {
API.LoadDB([{'cards': 'attacks'}, {'cards': 'battlegear'}, {'cards': 'creatures'}, {'cards': 'locations'}, {'cards': 'mugic'}])
.then(() => {
this.loaded = true;
this.search();
});
return (<Loading />);
}
let gen = (d, display, text) => {
let tmp = [];
Object.keys(this.input[d]).forEach((item, i) => {
tmp.push(<label style={{display: display}} key={i}><input type="checkbox" name={item} checked={this.input[d][item]} onChange={e => this.handleChange(e, d)} />{text(item)}</label>
);
});
return tmp;
}
let sets = gen("sets", "block", (item) => {
return API.sets[item.toUpperCase()];
});
let types = gen("types", "block", (item) => {
return item.charAt(0).toUpperCase()+item.slice(1);
});
let rarity = gen("rarity", "block", (item) => {
return item.split(" ").map(st => {return st.charAt(0).toUpperCase()+st.slice(1)}).join(" ");
});
// let gender = gen("gender", "block", (item) => {
// return item.charAt(0).toUpperCase()+item.slice(1);
// });
let tribes = gen("tribes", "inline", (item) => {
return (<span><img className="icon16" src={"/src/img/icons/tribes/"+item+".png"} />&nbsp;</span>);
});
let elements = gen("elements", "inline", (item) => {
return (<span><img className="icon16" src={"/src/img/icons/elements/"+item+".png"} />&nbsp;</span>);
}).slice(0, -2);
let disciplines = [];
Object.keys(this.input.disciplines).forEach((item, i) => {
disciplines.push(<label key={i} className="disciplines"><input type="text" name={item} value={this.input.disciplines[item]} onChange={e => this.handleChange(e, "disciplines")} />
<img className="icon20" style={{verticalAlign: 'bottom'}} src={"/src/img/icons/disciplines/"+item+".png"} />&nbsp;
</label>);
});
return (
<div className="SearchForm">
<form onSubmit={this.search}>
<label>Name&nbsp;<input type="text" name="name" value={this.input.name} onChange={this.handleChange} /></label>
<br />
<label>Text&nbsp;&nbsp;&nbsp;&nbsp;<input type="text" name="text" value={this.input.text} onChange={this.handleChange} /></label>
<br />
<label>Subtypes | Initiative<br />
<input type="text" name="subtypes" value={this.input.subtypes} onChange={this.handleChange} />
</label><br />
<label><input type="checkbox" name="past" checked={this.input.past} onChange={this.handleChange} />Past</label>&nbsp;
<label><input type="checkbox" name="mirage" checked={this.input.mirage} onChange={this.handleChange} />Mirage</label>
<br /><br />
<span>Tribes</span>
<br />
{tribes}
<br /> <br />
<span>Elements</span>
<br />
{elements}&nbsp;
<input type="button" value="or" className="and" disabled={!this.input.elements.and} onClick={(e)=>{this.input.elements.and=false;}} />
<input type="button" value="and" className="and" disabled={this.input.elements.and} onClick={(e)=>{this.input.elements.and=true;}} />
<br />
<label><input type="checkbox" name="none" checked={this.input.elements.none} onChange={e => this.handleChange(e, "elements")} />None</label>
<br /> <br />
<span>Disciplines</span>
<br />
{disciplines}
<br /> <br />
<span>Energy</span>
<br />
<label className="mcbp">Min:&nbsp;<input type="text" name="min" value={this.input.energy.min} onChange={e => this.handleChange(e, "energy")} /></label>&nbsp;
<label className="mcbp">Max:&nbsp;<input type="text" name="max" value={this.input.energy.max} onChange={e => this.handleChange(e, "energy")} /></label>
<br /><br />
<span>Mugic Counters/Cost
<br />Build Points</span>
<br />
<label className="mcbp">Min:&nbsp;<input type="text" name="min" value={this.input.mcbp.min} onChange={e => this.handleChange(e, "mcbp")} /></label>&nbsp;
<label className="mcbp">Max:&nbsp;<input type="text" name="max" value={this.input.mcbp.max} onChange={e => this.handleChange(e, "mcbp")} /></label>
<br /><br />
<label className="mull"><input type="checkbox" name="unique" checked={this.input.mull.unique} onChange={e => this.handleChange(e, "mull")} />Unique</label>&nbsp;
<label className="mull"><input type="checkbox" name="loyal" checked={this.input.mull.loyal} onChange={e => this.handleChange(e, "mull")} />Loyal</label>&nbsp;
<label className="mull"><input type="checkbox" name="legendary" checked={this.input.mull.legendary} onChange={e => this.handleChange(e, "mull")} />Legendary</label>
<br />
<label className="mull"><input type="checkbox" name="mixed" checked={this.input.mull.mixed} onChange={e => this.handleChange(e, "mull")} />Non-Loyal</label>
<br /><br />
<Collapsible trigger="Rarity">{rarity}</Collapsible>
<Collapsible trigger="Types">{types}</Collapsible>
<Collapsible trigger="Sets">{sets}</Collapsible>
{/*<Collapsible trigger="Gender (fan content)">{gender}</Collapsible>*/}
<br />
<input type="submit" value="Search" />&nbsp;&nbsp;&nbsp;&nbsp;
<input type="button" value="Reset" onClick={this.reset} />
</form>
</div>
);
}
handleChange = (event, obj) => {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
if (!obj) this.input[name] = value;
else this.input[obj][name] = value;
}
reset = (event) => {
event.preventDefault();
event.stopPropagation();
this.cleanInput();
}
search = (e) => {
if (e) {
e.preventDefault();
e.stopPropagation();
this.updateQuery();
}
// Sort data descending alphabetically
let filter = this.filter.addCollection('filter');
var pview = filter.addDynamicView('filter');
pview.applySimpleSort('gsx$name');
// begin data filtering
let attackResults = API.cards.attacks.chain();
let battlegearResults = API.cards.battlegear.chain();
let creatureResults = API.cards.creatures.chain();
let locationResults = API.cards.locations.chain();
let mugicResults = API.cards.mugic.chain();
// ignore cards with no set
attackResults = attackResults.where((obj) =>
{return (obj.gsx$set != ('') );}
);
battlegearResults = battlegearResults.where((obj) =>
{return (obj.gsx$set != ('') );}
);
creatureResults = creatureResults.where((obj) =>
{return (obj.gsx$set != ('') );}
);
locationResults = locationResults.where((obj) =>
{return (obj.gsx$set != ('') );}
);
mugicResults = mugicResults.where((obj) =>
{return (obj.gsx$set != ('') );}
);
// Search by name
if (this.input.name.length > 0) {
// clean name
let inputname = this.input.name.replace(/\\/g, '').replace(/\(|\)/g, (match) => {return ("\\"+match)});
attackResults = attackResults.find({'$or': [
{'gsx$name': {'$regex': new RegExp(inputname, 'i')}},
{'gsx$tags': {'$regex': new RegExp(inputname, 'i')}},
]});
battlegearResults = battlegearResults.find({'$or': [
{'gsx$name': {'$regex': new RegExp(inputname, 'i')}},
{'gsx$tags': {'$regex': new RegExp(inputname, 'i')}},
]});
creatureResults = creatureResults.find({'$or': [
{'gsx$name': {'$regex': new RegExp(inputname, 'i')}},
{'gsx$tags': {'$regex': new RegExp(inputname, 'i')}},
]});
locationResults = locationResults.find({'$or': [
{'gsx$name': {'$regex': new RegExp(inputname, 'i')}},
{'gsx$tags': {'$regex': new RegExp(inputname, 'i')}}
]});
mugicResults = mugicResults.find({'$or': [
{'gsx$name': {'$regex': new RegExp(inputname, 'i')}},
{'gsx$tags': {'$regex': new RegExp(inputname, 'i')}},
]});
}
// Text
if (this.input.text.length > 0) {
let textList = this.input.text.split(",").filter(Boolean).map((item) => {
return ({'$regex': new RegExp(item.trim(), 'i')});
});
attackResults = attackResults.find({'$or': [
{'gsx$tags': {"$or": textList}},
{'gsx$ability': {"$or": textList}},
{'gsx$flavortext': {"$or": textList}},
{'gsx$artist': {"$or": textList}}
]});
battlegearResults = battlegearResults.find({'$or': [
{'gsx$tags': {"$or": textList}},
{'gsx$ability': {"$or": textList}},
{'gsx$flavortext': {"$or": textList}},
{'gsx$artist': {"$or": textList}}
]});
creatureResults = creatureResults.find({'$or': [
{'gsx$tags': {"$or": textList}},
{'gsx$ability': {"$or": textList}},
{'gsx$flavortext': {"$or": textList}},
{'gsx$brainwashed': {"$or": textList}},
{'gsx$artist': {"$or": textList}}
]});
locationResults = locationResults.find({'$or': [
{'gsx$tags': {"$or": textList}},
{'gsx$ability': {"$or": textList}},
{'gsx$flavortext': {"$or": textList}},
{'gsx$artist': {"$or": textList}}
]});
mugicResults = mugicResults.find({'$or': [
{'gsx$tags': {"$or": textList}},
{'gsx$ability': {"$or": textList}},
{'gsx$flavortext': {"$or": textList}},
{'gsx$artist': {"$or": textList}}
]});
}
// Past
if (this.input.past) {
attackResults = attackResults.find({'gsx$past': {'$gt': 0}});
battlegearResults = battlegearResults.find({'gsx$past': {'$gt': 0}});
creatureResults = creatureResults.find({'gsx$types': {'$regex': new RegExp("past", 'i')}});
locationResults = locationResults.find({'gsx$past': {'$gt': 0}});
mugicResults = mugicResults.find({'gsx$past': {'$gt': 0}});
}
// Mirage
if (this.input.mirage) {
locationResults = locationResults.find({'gsx$mirage': {'$gt': 0}});
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.limit(0);
creatureResults = creatureResults.limit(0);
mugicResults = mugicResults.limit(0);
}
// Subtypes / Initiative
if (this.input.subtypes.length > 0) {
let subtypesList = this.input.subtypes.split(",").filter(Boolean).map((item) => {
return ({'$regex': new RegExp(item.trim(), 'i')});
});
creatureResults = creatureResults.find({'gsx$types': {'$or': subtypesList} });
locationResults = locationResults.find({'gsx$initiative': {'$or': subtypesList}});
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.limit(0);
mugicResults = mugicResults.limit(0);
}
// Search by tribe
let tribesList = [];
for (const tribe in this.input.tribes) {
if (this.input.tribes[tribe])
tribesList.push({'$regex': new RegExp(tribe, 'i')});
}
if (tribesList.length > 0) {
creatureResults = creatureResults.find({'gsx$tribe': {'$or': tribesList} });
mugicResults = mugicResults.find({'gsx$tribe': {'$or': tribesList} });
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.limit(0);
locationResults = locationResults.limit(0);
}
// Search by elements
if (this.input.elements.none) {
attackResults = attackResults.where(
(obj) => {return (obj.gsx$fire == ('') );}
).where(
(obj) => {return (obj.gsx$air == ('') );}
).where(
(obj) => {return (obj.gsx$earth == ('') );}
).where(
(obj) => {return (obj.gsx$water == ('') );}
);
battlegearResults = battlegearResults.limit(0);
creatureResults = creatureResults.where(obj => (obj.gsx$elements == ''));
locationResults = locationResults.limit(0);
mugicResults = mugicResults.limit(0);
}
else {
let elementsList = [];
let elementsList2 = [];
for (const element in this.input.elements) {
if (element === "none" || element === "and") continue;
if (this.input.elements[element]) {
elementsList.push({'$regex': new RegExp(element, 'i')});
elementsList2.push({['gsx$'+element]: {'$gte': 0}})
}
}
if (elementsList.length > 0) {
if (this.input.elements.and) {
creatureResults = creatureResults.find({'gsx$elements': {'$and': elementsList} });
attackResults = attackResults.find({'$and': elementsList2});
}
else {
creatureResults = creatureResults.find({'gsx$elements': {'$or': elementsList} });
attackResults = attackResults.find({'$or': elementsList2});
}
battlegearResults = battlegearResults.limit(0);
locationResults = locationResults.limit(0);
mugicResults = mugicResults.limit(0);
}
}
// Stats
if (this.input.disciplines.courage > 0)
creatureResults = creatureResults.find({'gsx$courage': {'$gte': this.input.disciplines.courage}});
if (this.input.disciplines.power > 0)
creatureResults = creatureResults.find({'gsx$power': {'$gte': this.input.disciplines.power}});
if (this.input.disciplines.wisdom > 0)
creatureResults = creatureResults.find({'gsx$wisdom': {'$gte': this.input.disciplines.wisdom}});
if (this.input.disciplines.speed > 0)
creatureResults = creatureResults.find({'gsx$speed': {'$gte': this.input.disciplines.speed}});
if (this.input.energy.min > 0)
creatureResults = creatureResults.find({'gsx$energy': {'$gte': this.input.energy.min}});
if (this.input.energy.max > 0 && this.input.energy.max >= this.input.energy.min)
creatureResults = creatureResults.find({'gsx$energy': {'$lte': this.input.energy.max}});
// (if any stats, filter out non-Creatures)
if (this.input.energy.min > 0 || this.input.energy.max > 0 || this.input.disciplines.courage > 0 || this.input.disciplines.power > 0 || this.input.disciplines.wisdom > 0 || this.input.disciplines.speed > 0) {
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.limit(0);
locationResults = locationResults.limit(0);
mugicResults = mugicResults.limit(0);
}
// Mugic Counters/Cost | Build Points
if (this.input.mcbp.min !== "" && this.input.mcbp.min >= 0) {
attackResults = attackResults.find({'gsx$bp': {'$gte': this.input.mcbp.min}});
creatureResults = creatureResults.find({'gsx$mugicability': {'$gte': this.input.mcbp.min}});
mugicResults = mugicResults.find({'gsx$cost': {'$gte': this.input.mcbp.min}});
}
if (this.input.mcbp.max !== "" && this.input.mcbp.max >= 0 && this.input.mcbp.max >= this.input.mcbp.min) {
attackResults = attackResults.find({'gsx$bp': {'$lte': this.input.mcbp.max}});
creatureResults = creatureResults.find({'gsx$mugicability': {'$lte': this.input.mcbp.max}});
mugicResults = mugicResults.find({'gsx$cost': {'$lte': this.input.mcbp.max}});
}
// filter out Battlegear and Locations if mcbp
if (this.input.mcbp.max > 0 || this.input.mcbp.min > 0) {
battlegearResults = battlegearResults.limit(0);
locationResults = locationResults.limit(0);
}
// Unique
if (this.input.mull.unique) {
attackResults = attackResults.find({'gsx$unique': {'$gt': 0}});
battlegearResults = battlegearResults.find({'gsx$unique': {'$gt': 0}});
creatureResults = creatureResults.find({'gsx$unique': {'$gt': 0}});
locationResults = locationResults.find({'gsx$unique': {'$gt': 0}});
mugicResults = mugicResults.find({'gsx$unique': {'$gt': 0}});
}
// Loyal
if (this.input.mull.loyal) {
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.find({'gsx$loyal': {'$gt': 0}});
creatureResults = creatureResults.find({'gsx$loyal': {'$gt': 0}});
mugicResults = mugicResults.limit(0);
locationResults = locationResults.limit(0);
}
// Legendary
if (this.input.mull.legendary) {
attackResults = attackResults.find({'gsx$legendary': {'$gt': 0}});
battlegearResults = battlegearResults.find({'gsx$legendary': {'$gt': 0}});
creatureResults = creatureResults.find({'gsx$legendary': {'$gt': 0}});
locationResults = locationResults.find({'gsx$legendary': {'$gt': 0}});
mugicResults = mugicResults.find({'gsx$legendary': {'$gt': 0}});
}
// Non Loyal
if (this.input.mull.mixed) {
attackResults = attackResults.limit(0);
creatureResults = creatureResults.find({'gsx$loyal': {'$lte': 0}});
battlegearResults = battlegearResults.find({'gsx$loyal': {'$lte': 0}});
mugicResults = mugicResults.limit(0);
locationResults = locationResults.limit(0);
}
// Sets
let setsList = [];
for (const key in this.input.sets) {
if (this.input.sets[key])
setsList.push({'$eq': key.toUpperCase()});
}
if (setsList.length > 0) {
attackResults = attackResults.find({'gsx$set': {'$or': setsList} });
battlegearResults = battlegearResults.find({'gsx$set': {'$or': setsList} });
creatureResults = creatureResults.find({'gsx$set': {'$or': setsList} });
locationResults = locationResults.find({'gsx$set': {'$or': setsList} });
mugicResults = mugicResults.find({'gsx$set': {'$or': setsList} });
}
// Rarity
let rarityList = [];
for (const key in this.input.rarity) {
if (this.input.rarity[key])
rarityList.push({'$eq': key.split(" ").map(st => {return st.charAt(0).toUpperCase()+st.slice(1)}).join(" ")});
}
if (rarityList.length > 0) {
attackResults = attackResults.find({'gsx$rarity': {'$or': rarityList} });
battlegearResults = battlegearResults.find({'gsx$rarity': {'$or': rarityList} });
creatureResults = creatureResults.find({'gsx$rarity': {'$or': rarityList} });
locationResults = locationResults.find({'gsx$rarity': {'$or': rarityList} });
mugicResults = mugicResults.find({'gsx$rarity': {'$or': rarityList} });
}
// Gender
// let genderList = [];
// for (const key in this.input.gender) {
// if (this.input.gender[key])
// genderList.push({'$regex': new RegExp(key, 'i')})
// }
// if (genderList.length > 0) {
// attackResults = attackResults.limit(0);
// battlegearResults = battlegearResults.limit(0);
// creatureResults = creatureResults.find({'gsx$gender': {'$or': genderList} });
// locationResults = locationResults.limit(0);
// mugicResults = mugicResults.limit(0);
// }
// Merge data
let types = !(this.input.types.attack | this.input.types.battlegear | this.input.types.creature | this.input.types.location | this.input.types.mugic);
if (types || this.input.types.attack) {
let temp = attackResults.data();
temp.forEach(function(v){ delete v.$loki });
filter.insert(temp);
}
if (types || this.input.types.battlegear) {
let temp = battlegearResults.data();
temp.forEach(function(v){ delete v.$loki });
filter.insert(temp);
}
if (types || this.input.types.creature) {
let temp = creatureResults.data()
temp.forEach(function(v){ delete v.$loki });
filter.insert(temp);
}
if (types || this.input.types.location) {
let temp = locationResults.data()
temp.forEach(function(v){ delete v.$loki });
filter.insert(temp);
}
if (types || this.input.types.mugic) {
let temp = mugicResults.data()
temp.forEach(function(v){ delete v.$loki });
filter.insert(temp);
}
let results = pview.data();
this.filter.removeCollection('filter');
if (results.length > 0) this.props.handleContent(results);
else this.props.handleContent([{'text': 'No Results Found'}]);
}
}

View File

@ -4,7 +4,7 @@ import s from '../../styles/app.style';
import {observable} from "mobx";
import {observer, inject} from 'mobx-react';
import CardList from './List';
import SearchForm from './Search';
import SearchForm from './search/index.js';
import '../../scss/collection.scss'
@inject((stores, props, context) => props) @observer

View File

@ -0,0 +1,272 @@
import React from 'react';
import {observable} from "mobx";
import {observer, inject} from 'mobx-react';
import Collapsible from 'react-collapsible';
import API from '../../SpreadsheetData';
import {Loading} from '../../Snippets';
import search_api from './search';
@inject((stores, props, context) => props) @observer
export default class SearchCollection extends React.Component {
@observable loaded = false;
@observable input;
list = ["sets", "types", "rarity", "tribes", "elements", "mull", "gender"];
constructor(props) {
super(props);
// Binding for keeping scope with dom functions
this.search = this.search.bind(this);
this.handleChange = this.handleChange.bind(this);
this.reset = this.reset.bind(this);
this.props.handleContent([{'text': 'Loading...'}]);
this.cleanInput();
this.parseQuery();
}
cleanInput = () => {
let input = {
name: "",
text: "",
subtypes: "",
past: false,
mirage: false,
minion: false,
flavor: true,
sets: {},
types: {attack: false, battlegear: false, creature: false, location: false, mugic: false},
rarity: {common: false, uncommon: false, rare: false, 'super rare': false, 'ultra rare': false, promo: false},
tribes: {danian: false, 'm\'arrillian': false, 'mipedian': false, overworld: false, underworld: false, generic: false},
elements: {fire: false, air: false, earth: false, water: false, none: false, and: false},
disciplines: {courage: '', power: '', wisdom: '', speed: ''},
energy: {min: '', max: ''},
mcbp: {min: '', max: ''},
mull: {unique: false, loyal: false, legendary: false, mixed: false},
gender: {ambiguous: false, female: false, male: false}
};
for (const key in API.sets) input.sets[key.toLowerCase()] = false;
this.input = input;
}
parseQuery = () => {
const queryString = this.props.location.search.toLowerCase();
let query = {};
let pairs = (queryString[0] === '?' ? queryString.substr(1) : queryString).split('&');
for (let i = 0; i < pairs.length; i++) {
let pair = pairs[i].split('=');
query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || '');
}
// query -> input
this.list.forEach((d) => {
if (query[d]) {
query[d].split(',').map(item => {
this.input[d][item] = true;
});
}
});
if (query.hasOwnProperty('past')) this.input.past = true;
if (query.hasOwnProperty('mirage')) this.input.mirage = true;
if (query.hasOwnProperty('minion')) this.input.minion = true;
if (query.hasOwnProperty('name')) this.input.name = query.name;
if (query.hasOwnProperty('text')) this.input.text = query.text;
if (query.hasOwnProperty('subtypes')) this.input.subtypes = query.subtypes;
if (query.hasOwnProperty('courage')) this.input.disciplines.courage = query.courage;
if (query.hasOwnProperty('power')) this.input.disciplines.power = query.power;
if (query.hasOwnProperty('wisdom')) this.input.disciplines.wisdom = query.wisdom;
if (query.hasOwnProperty('speed')) this.input.disciplines.speed = query.speed;
if (query.hasOwnProperty('energy')) {
let q = query.energy.split(',');
if (q[0] >= 0) this.input.energy.min = q[0];
if (q[1] >= 0) this.input.energy.max = q[1];
}
if (query.hasOwnProperty('mcbp')) {
let q = query.mcbp.split(',');
if (q[0] >= 0) this.input.mcbp.min = q[0];
if (q[1] >= 0) this.input.mcbp.max = q[1];
}
}
async updateQuery() {
let queryString = "";
let update = (query) => {
let temp = "";
Object.keys(this.input[query]).forEach((item) => {
if (this.input[query][item] == true) temp += item + ",";
});
if (temp.length > 0) return query + "=" + temp.replace(/\,$/, '&');
else return "";
}
this.list.forEach(item => queryString += update(item));
if (this.input.past) queryString += "past&";
if (this.input.mirage) queryString += "mirage&";
if (this.input.minion) queryString += "minion&";
if (this.input.name) queryString += "name=" + encodeURIComponent(this.input.name) + "&";
if (this.input.text) queryString += "text=" + encodeURIComponent(this.input.text) + "&";
if (this.input.subtypes) queryString += "subtypes=" + encodeURIComponent(this.input.subtypes) + "&";
if (this.input.disciplines.courage > 0) queryString += "courage=" + this.input.disciplines.courage + "&";
if (this.input.disciplines.power > 0) queryString += "power=" + this.input.disciplines.power + "&";
if (this.input.disciplines.wisdom > 0) queryString += "wisdom=" + this.input.disciplines.wisdom + "&";
if (this.input.disciplines.speed > 0) queryString += "speed=" + this.input.disciplines.speed + "&";
if (this.input.energy.min != "" || this.input.energy.max != "") {
queryString += "energy=";
if (this.input.energy.min != "" && this.input.energy.min >= 0) queryString += this.input.energy.min;
queryString += ",";
if (this.input.energy.max != "" && this.input.energy.max >= 0) queryString += this.input.energy.max;
queryString += "&";
}
if (this.input.mcbp.min != "" || this.input.mcbp.max != "") {
queryString += "mcbp=";
if (this.input.mcbp.min != "" && this.input.mcbp.min >= 0) queryString += this.input.mcbp.min;
queryString += ",";
if (this.input.mcbp.max != "" && this.input.mcbp.max >= 0) queryString += this.input.mcbp.max;
queryString += "&";
}
// Strip trailing &
queryString = queryString.replace(/\&$/, '');
// Push to URL
this.props.history.push('/collection/?'+(queryString));
}
reset = (event) => {
event.preventDefault();
event.stopPropagation();
this.cleanInput();
}
handleChange = (event, obj) => {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
if (!obj) this.input[name] = value;
else this.input[obj][name] = value;
}
search = (e) => {
if (e) {
e.preventDefault();
e.stopPropagation();
this.updateQuery();
}
let results = search_api(this.input);
if (results.length > 0) this.props.handleContent(results);
else this.props.handleContent([{'text': 'No Results Found'}]);
}
render() {
if (this.loaded == false) {
API.LoadDB([{'cards': 'attacks'}, {'cards': 'battlegear'}, {'cards': 'creatures'}, {'cards': 'locations'}, {'cards': 'mugic'}])
.then(() => {
this.loaded = true;
this.search();
});
return (<Loading />);
}
let gen = (d, display, text) => {
let tmp = [];
Object.keys(this.input[d]).forEach((item, i) => {
tmp.push(<label style={{display: display}} key={i}><input type="checkbox" name={item} checked={this.input[d][item]} onChange={e => this.handleChange(e, d)} />{text(item)}</label>
);
});
return tmp;
}
let sets = gen("sets", "block", (item) => {
return API.sets[item.toUpperCase()];
});
let types = gen("types", "block", (item) => {
return item.charAt(0).toUpperCase()+item.slice(1);
});
let rarity = gen("rarity", "block", (item) => {
return item.split(" ").map(st => {return st.charAt(0).toUpperCase()+st.slice(1)}).join(" ");
});
// let gender = gen("gender", "block", (item) => {
// return item.charAt(0).toUpperCase()+item.slice(1);
// });
let tribes = gen("tribes", "inline", (item) => {
return (<span><img className="icon16" src={"/src/img/icons/tribes/"+item+".png"} />&nbsp;</span>);
});
let elements = gen("elements", "inline", (item) => {
return (<span><img className="icon20" src={"/src/img/icons/elements/"+item+".png"} />&nbsp;</span>);
}).slice(0, -2);
let disciplines = [];
Object.keys(this.input.disciplines).forEach((item, i) => {
disciplines.push(<label key={i} className="disciplines"><input type="text" name={item} value={this.input.disciplines[item]} onChange={e => this.handleChange(e, "disciplines")} />
&nbsp;<img className="icon20" style={{verticalAlign: 'bottom'}} src={"/src/img/icons/disciplines/"+item+".png"} />&nbsp;
</label>);
});
return (
<div className="SearchForm">
<form onSubmit={this.search}>
<label className="bigger">Search</label>
<br />
<div className="text-entry">
<input type="text" name="name" placeholder="Card Name" value={this.input.name} onChange={this.handleChange} />
<br />
<input type="text" name="text" placeholder="Card Text" value={this.input.text} onChange={this.handleChange} />
<br />
<label className="mull"><input type="checkbox" name="flavor" value={!this.input.flavor} onChange={(e) => {this.input.flavor = !e.target.checked}} />Ignore Flavortext</label>
<br />
<input type="text" name="subtypes" placeholder="Subtypes | Initiative" value={this.input.subtypes} onChange={this.handleChange} />
</div>
<label className="mull"><input type="checkbox" name="past" checked={this.input.past} onChange={this.handleChange} />Past</label>&nbsp;
<label className="mull"><input type="checkbox" name="mirage" checked={this.input.mirage} onChange={this.handleChange} />Mirage</label>&nbsp;
<label className="mull"><input type="checkbox" name="minion" checked={this.input.minion} onChange={this.handleChange} />Minion</label>
<br /><br />
<label className="mull"><input type="checkbox" name="unique" checked={this.input.mull.unique} onChange={e => this.handleChange(e, "mull")} />Unique</label>&nbsp;
<label className="mull"><input type="checkbox" name="loyal" checked={this.input.mull.loyal} onChange={e => this.handleChange(e, "mull")} />Loyal</label>&nbsp;
<label className="mull"><input type="checkbox" name="legendary" checked={this.input.mull.legendary} onChange={e => this.handleChange(e, "mull")} />Legendary</label>
<br />
<label className="mull"><input type="checkbox" name="mixed" checked={this.input.mull.mixed} onChange={e => this.handleChange(e, "mull")} />Non-Loyal</label>
<br /><hr />
{tribes}
<br /> <hr />
{elements}&nbsp;
<label className="none"><input type="checkbox" name="none" checked={this.input.elements.none} onChange={e => this.handleChange(e, "elements")} /><span>None</span></label>
<br />
<input type="button" value="or" className="and" disabled={!this.input.elements.and} onClick={(e)=>{this.input.elements.and=false;}} />
<input type="button" value="and" className="and" disabled={this.input.elements.and} onClick={(e)=>{this.input.elements.and=true;}} />
<br /> <hr />
{disciplines}
<br /> <hr />
<Collapsible open={true} trigger="Energy">
<label className="mcbp">Min:&nbsp;<input type="text" name="min" value={this.input.energy.min} onChange={e => this.handleChange(e, "energy")} /></label>&nbsp;
<label className="mcbp">Max:&nbsp;<input type="text" name="max" value={this.input.energy.max} onChange={e => this.handleChange(e, "energy")} /></label>
</Collapsible>
<Collapsible open={true} trigger="Build Points & Mugic Counters/Cost">
<label className="mcbp">Min:&nbsp;<input type="text" name="min" value={this.input.mcbp.min} onChange={e => this.handleChange(e, "mcbp")} /></label>&nbsp;
<label className="mcbp">Max:&nbsp;<input type="text" name="max" value={this.input.mcbp.max} onChange={e => this.handleChange(e, "mcbp")} /></label>
</Collapsible>
<Collapsible open={true} trigger="Types">{types}</Collapsible>
<Collapsible trigger="Rarity">{rarity}</Collapsible>
<Collapsible trigger="Sets">{sets}</Collapsible>
{/*<Collapsible trigger="Gender (fan content)">{gender}</Collapsible>*/}
<br />
<input type="submit" value="Search" />&nbsp;&nbsp;&nbsp;&nbsp;
<input type="button" value="Reset" onClick={this.reset} />
</form>
</div>
);
}
}

View File

@ -0,0 +1,341 @@
import loki from 'lokijs';
import API from '../../SpreadsheetData';
export default function search_api(input) {
// Sort data descending alphabetically
let filter = (new loki("filter.db")).addCollection('filter');
var pview = filter.addDynamicView('filter');
pview.applySimpleSort('gsx$name');
// begin data filtering
let attackResults = API.cards.attacks.chain();
let battlegearResults = API.cards.battlegear.chain();
let creatureResults = API.cards.creatures.chain();
let locationResults = API.cards.locations.chain();
let mugicResults = API.cards.mugic.chain();
// ignore cards with no set
attackResults = attackResults.where((obj) => {
return obj.gsx$set != ('');
});
battlegearResults = battlegearResults.where((obj) => {
return obj.gsx$set != ('');
});
creatureResults = creatureResults.where((obj) => {
return obj.gsx$set != ('');
});
locationResults = locationResults.where((obj) => {
return obj.gsx$set != ('');
});
mugicResults = mugicResults.where((obj) => {
return obj.gsx$set != ('');
});
// Search by name
if (input.name.length > 0) {
// clean name
let inputname = input.name.replace(/\\/g, '').replace(/\(|\)/g, (match) => {return ("\\"+match)});
attackResults = attackResults.find({'$or': [
{'gsx$name': {'$regex': new RegExp(inputname, 'i')}},
{'gsx$tags': {'$regex': new RegExp(inputname, 'i')}},
]});
battlegearResults = battlegearResults.find({'$or': [
{'gsx$name': {'$regex': new RegExp(inputname, 'i')}},
{'gsx$tags': {'$regex': new RegExp(inputname, 'i')}},
]});
creatureResults = creatureResults.find({'$or': [
{'gsx$name': {'$regex': new RegExp(inputname, 'i')}},
{'gsx$tags': {'$regex': new RegExp(inputname, 'i')}},
]});
locationResults = locationResults.find({'$or': [
{'gsx$name': {'$regex': new RegExp(inputname, 'i')}},
{'gsx$tags': {'$regex': new RegExp(inputname, 'i')}}
]});
mugicResults = mugicResults.find({'$or': [
{'gsx$name': {'$regex': new RegExp(inputname, 'i')}},
{'gsx$tags': {'$regex': new RegExp(inputname, 'i')}},
]});
}
// Card Text
if (input.text.length > 0) {
let textList = input.text.split(",").filter(Boolean).map((item) => {
return ({'$regex': new RegExp(item.trim(), 'i')});
});
let parm = (() => {
let list = [
{'gsx$tags': {"$or": textList}},
{'gsx$ability': {"$or": textList}},
{'gsx$artist': {"$or": textList}}
]
if (input.flavor)
list.splice(3, 0, {'gsx$flavortext': {"$or": textList}});
return list;
})();
attackResults = attackResults.find({'$or': parm});
battlegearResults = battlegearResults.find({'$or': parm});
let cparm = parm.push
creatureResults = creatureResults.find({'$or':
(parm.concat([{'gsx$brainwashed': {"$or": textList}}]))
});
locationResults = locationResults.find({'$or': parm});
mugicResults = mugicResults.find({'$or': parm});
}
// Past
if (input.past) {
attackResults = attackResults.find({'gsx$past': {'$gt': 0}});
battlegearResults = battlegearResults.find({'gsx$past': {'$gt': 0}});
creatureResults = creatureResults.find({'gsx$types': {'$regex': new RegExp("past", 'i')}});
locationResults = locationResults.find({'gsx$past': {'$gt': 0}});
mugicResults = mugicResults.find({'gsx$past': {'$gt': 0}});
}
// Mirage
if (input.mirage) {
locationResults = locationResults.find({'gsx$mirage': {'$gt': 0}});
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.limit(0);
creatureResults = creatureResults.limit(0);
mugicResults = mugicResults.limit(0);
}
// Subtypes / Initiative
if (input.subtypes.length > 0) {
let subtypesList = input.subtypes.split(",").filter(Boolean).map((item) => {
return ({'$regex': new RegExp(item.trim(), 'i')});
});
creatureResults = creatureResults.find({'gsx$types': {'$or': subtypesList} });
locationResults = locationResults.find({'gsx$initiative': {'$or': subtypesList}});
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.limit(0);
mugicResults = mugicResults.limit(0);
}
// Minion
if (input.minion) {
locationResults = locationResults.limit(0);
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.limit(0);
creatureResults = creatureResults.where((obj) => {
return obj.gsx$brainwashed != ('');
});
mugicResults = mugicResults.limit(0);
}
// Search by tribe
let tribesList = [];
for (const tribe in input.tribes) {
if (input.tribes[tribe])
tribesList.push({'$regex': new RegExp(tribe, 'i')});
}
if (tribesList.length > 0) {
creatureResults = creatureResults.find({'gsx$tribe': {'$or': tribesList} });
mugicResults = mugicResults.find({'gsx$tribe': {'$or': tribesList} });
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.limit(0);
locationResults = locationResults.limit(0);
}
// Search by elements
if (input.elements.none) {
attackResults = attackResults.where(
(obj) => {return (obj.gsx$fire == ('') );}
).where(
(obj) => {return (obj.gsx$air == ('') );}
).where(
(obj) => {return (obj.gsx$earth == ('') );}
).where(
(obj) => {return (obj.gsx$water == ('') );}
);
battlegearResults = battlegearResults.limit(0);
creatureResults = creatureResults.where(obj => (obj.gsx$elements == ''));
locationResults = locationResults.limit(0);
mugicResults = mugicResults.limit(0);
}
else {
let elementsList = [];
let elementsList2 = [];
for (const element in input.elements) {
if (element === "none" || element === "and") continue;
if (input.elements[element]) {
elementsList.push({'$regex': new RegExp(element, 'i')});
elementsList2.push({['gsx$'+element]: {'$gte': 0}})
}
}
if (elementsList.length > 0) {
if (input.elements.and) {
creatureResults = creatureResults.find({'gsx$elements': {'$and': elementsList} });
attackResults = attackResults.find({'$and': elementsList2});
}
else {
creatureResults = creatureResults.find({'gsx$elements': {'$or': elementsList} });
attackResults = attackResults.find({'$or': elementsList2});
}
battlegearResults = battlegearResults.limit(0);
locationResults = locationResults.limit(0);
mugicResults = mugicResults.limit(0);
}
}
// Stats
if (input.disciplines.courage > 0)
creatureResults = creatureResults.find({'gsx$courage': {'$gte': input.disciplines.courage}});
if (input.disciplines.power > 0)
creatureResults = creatureResults.find({'gsx$power': {'$gte': input.disciplines.power}});
if (input.disciplines.wisdom > 0)
creatureResults = creatureResults.find({'gsx$wisdom': {'$gte': input.disciplines.wisdom}});
if (input.disciplines.speed > 0)
creatureResults = creatureResults.find({'gsx$speed': {'$gte': input.disciplines.speed}});
if (input.energy.min > 0)
creatureResults = creatureResults.find({'gsx$energy': {'$gte': input.energy.min}});
if (input.energy.max > 0 && input.energy.max >= input.energy.min)
creatureResults = creatureResults.find({'gsx$energy': {'$lte': input.energy.max}});
// (if any stats, filter out non-Creatures)
if (input.energy.min > 0 || input.energy.max > 0 || input.disciplines.courage > 0 || input.disciplines.power > 0 || input.disciplines.wisdom > 0 || input.disciplines.speed > 0) {
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.limit(0);
locationResults = locationResults.limit(0);
mugicResults = mugicResults.limit(0);
}
// Mugic Counters/Cost | Build Points
if (input.mcbp.min !== "" && input.mcbp.min >= 0) {
attackResults = attackResults.find({'gsx$bp': {'$gte': input.mcbp.min}});
creatureResults = creatureResults.find({'gsx$mugicability': {'$gte': input.mcbp.min}});
mugicResults = mugicResults.find({'gsx$cost': {'$gte': input.mcbp.min}});
}
if (input.mcbp.max !== "" && input.mcbp.max >= 0 && input.mcbp.max >= input.mcbp.min) {
attackResults = attackResults.find({'gsx$bp': {'$lte': input.mcbp.max}});
creatureResults = creatureResults.find({'gsx$mugicability': {'$lte': input.mcbp.max}});
mugicResults = mugicResults.find({'gsx$cost': {'$lte': input.mcbp.max}});
}
// filter out Battlegear and Locations if mcbp
if (input.mcbp.max > 0 || input.mcbp.min > 0) {
battlegearResults = battlegearResults.limit(0);
locationResults = locationResults.limit(0);
}
// Unique
if (input.mull.unique) {
attackResults = attackResults.find({'gsx$unique': {'$gt': 0}});
battlegearResults = battlegearResults.find({'gsx$unique': {'$gt': 0}});
creatureResults = creatureResults.find({'gsx$unique': {'$gt': 0}});
locationResults = locationResults.find({'gsx$unique': {'$gt': 0}});
mugicResults = mugicResults.find({'gsx$unique': {'$gt': 0}});
}
// Loyal
if (input.mull.loyal) {
attackResults = attackResults.limit(0);
battlegearResults = battlegearResults.find({'gsx$loyal': {'$gt': 0}});
creatureResults = creatureResults.find({'gsx$loyal': {'$gt': 0}});
mugicResults = mugicResults.limit(0);
locationResults = locationResults.limit(0);
}
// Legendary
if (input.mull.legendary) {
attackResults = attackResults.find({'gsx$legendary': {'$gt': 0}});
battlegearResults = battlegearResults.find({'gsx$legendary': {'$gt': 0}});
creatureResults = creatureResults.find({'gsx$legendary': {'$gt': 0}});
locationResults = locationResults.find({'gsx$legendary': {'$gt': 0}});
mugicResults = mugicResults.find({'gsx$legendary': {'$gt': 0}});
}
// Non Loyal
if (input.mull.mixed) {
attackResults = attackResults.limit(0);
creatureResults = creatureResults.find({'gsx$loyal': {'$lte': 0}});
battlegearResults = battlegearResults.find({'gsx$loyal': {'$lte': 0}});
mugicResults = mugicResults.limit(0);
locationResults = locationResults.limit(0);
}
// Sets
let setsList = [];
for (const key in input.sets) {
if (input.sets[key])
setsList.push({'$eq': key.toUpperCase()});
}
if (setsList.length > 0) {
attackResults = attackResults.find({'gsx$set': {'$or': setsList} });
battlegearResults = battlegearResults.find({'gsx$set': {'$or': setsList} });
creatureResults = creatureResults.find({'gsx$set': {'$or': setsList} });
locationResults = locationResults.find({'gsx$set': {'$or': setsList} });
mugicResults = mugicResults.find({'gsx$set': {'$or': setsList} });
}
// Rarity
let rarityList = [];
for (const key in input.rarity) {
if (input.rarity[key])
rarityList.push({'$eq': key.split(" ").map(st => {return st.charAt(0).toUpperCase()+st.slice(1)}).join(" ")});
}
if (rarityList.length > 0) {
attackResults = attackResults.find({'gsx$rarity': {'$or': rarityList} });
battlegearResults = battlegearResults.find({'gsx$rarity': {'$or': rarityList} });
creatureResults = creatureResults.find({'gsx$rarity': {'$or': rarityList} });
locationResults = locationResults.find({'gsx$rarity': {'$or': rarityList} });
mugicResults = mugicResults.find({'gsx$rarity': {'$or': rarityList} });
}
// Gender
// let genderList = [];
// for (const key in input.gender) {
// if (input.gender[key])
// genderList.push({'$regex': new RegExp(key, 'i')})
// }
// if (genderList.length > 0) {
// attackResults = attackResults.limit(0);
// battlegearResults = battlegearResults.limit(0);
// creatureResults = creatureResults.find({'gsx$gender': {'$or': genderList} });
// locationResults = locationResults.limit(0);
// mugicResults = mugicResults.limit(0);
// }
// Merge data
let types = !(input.types.attack | input.types.battlegear | input.types.creature | input.types.location | input.types.mugic);
if (types || input.types.attack) {
let temp = attackResults.data();
temp.forEach(function(v){ delete v.$loki });
filter.insert(temp);
}
if (types || input.types.battlegear) {
let temp = battlegearResults.data();
temp.forEach(function(v){ delete v.$loki });
filter.insert(temp);
}
if (types || input.types.creature) {
let temp = creatureResults.data()
temp.forEach(function(v){ delete v.$loki });
filter.insert(temp);
}
if (types || input.types.location) {
let temp = locationResults.data()
temp.forEach(function(v){ delete v.$loki });
filter.insert(temp);
}
if (types || input.types.mugic) {
let temp = mugicResults.data()
temp.forEach(function(v){ delete v.$loki });
filter.insert(temp);
}
return pview.data();
}

View File

@ -2,19 +2,31 @@
@media only screen and (min-width: 975px) {
.collection {
margin-top: 5px;
margin-right: 5px;
margin-left: 5px;
> .left {
float: left;
width: 30%;
.collection {
margin-top: 5px;
margin-right: 5px;
margin-left: 5px;
> .left {
float: left;
width: 30%;
}
> .right {
float: right;
width: 70%;
}
}
> .right {
float: right;
width: 70%;
}
.collection {
@media only screen and (min-width: 975px) {
.text-entry {
input[type="text"] {
margin-bottom: 2px;
width: 200px;
}
}
@ -61,6 +73,7 @@
.SearchForm {
text-align: left;
padding-top: 3px;
}
.brainwashed {
@ -80,7 +93,8 @@
margin-top: 2px;
}
.mull input {
.mull input,
.Collapsible__contentInner input {
vertical-align: middle;
}
@ -152,6 +166,14 @@
background-color: grey;
}
.Collapsible__contentOuter {
margin-top: 4px;
}
.Collapsible__contentInner {
margin-left: 2px;
}
.left {
position: relative;
}
@ -193,3 +215,28 @@
max-height: 350px;
}
}
hr {
width: 250px;
margin-inline-start: 0;
}
.none {
display:inline;
> span {
top: -3px;
position: relative;
}
}
label {
user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-webkit-touch-callout: none;
-o-user-select: none;
-moz-user-select: none;
}
} // Collection Specific Styling