diff --git a/package.json b/package.json
index 4dfd19d..fee1c7c 100644
--- a/package.json
+++ b/package.json
@@ -11,12 +11,14 @@
"dependencies": {
"buefy": "^0.8.2",
"core-js": "^2.6.5",
+ "idb": "^4.0.4",
"register-service-worker": "^1.6.2",
"vue": "^2.6.10",
"vue-class-component": "^7.0.2",
"vue-property-decorator": "^8.1.0",
"vue-router": "^3.0.3",
- "vuex": "^3.0.1"
+ "vuex": "^3.0.1",
+ "vuex-class": "^0.3.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.11.0",
diff --git a/src/App.vue b/src/App.vue
index e086ec2..60f68c6 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,16 +1,33 @@
-
+
+
+ {{ loading }}
+
-
diff --git a/src/assets/scss/app.scss b/src/assets/scss/app.scss
index a378a0f..04c592c 100644
--- a/src/assets/scss/app.scss
+++ b/src/assets/scss/app.scss
@@ -3,4 +3,13 @@
@import "variables";
@import "~bulma/sass/utilities/derived-variables";
@import "~bulma";
-@import "~buefy/src/scss/buefy";
\ No newline at end of file
+@import "~buefy/src/scss/buefy";
+
+html {
+ scrollbar-color: #404245 #2f3132;
+ background-color: #2a2c2e;
+}
+
+body {
+ color: white;
+}
\ No newline at end of file
diff --git a/src/mlpccg/card.ts b/src/mlpccg/card.ts
new file mode 100644
index 0000000..00966da
--- /dev/null
+++ b/src/mlpccg/card.ts
@@ -0,0 +1,5 @@
+const imgBaseURL = "https://mcg.zyg.ovh/images/cards/";
+
+export function cardImageURL(cardid: string): string {
+ return `${imgBaseURL}${cardid}.webp`;
+}
diff --git a/src/mlpccg/database.ts b/src/mlpccg/database.ts
new file mode 100644
index 0000000..7ca0a86
--- /dev/null
+++ b/src/mlpccg/database.ts
@@ -0,0 +1,35 @@
+import { DBSchema, openDB } from "idb";
+import { Card } from "./types";
+
+interface CardDB extends DBSchema {
+ card: {
+ key: string;
+ value: Card;
+ indexes: {
+ "by-set": string;
+ "by-element": string[];
+ "by-type": string;
+ "by-cost": number;
+ "by-power": number;
+ "by-rarity": string;
+ };
+ };
+}
+
+const cardDBName = "card-db";
+
+export async function openCardDB() {
+ return await openDB(cardDBName, 1, {
+ upgrade(db) {
+ const cardStore = db.createObjectStore("card", {
+ keyPath: "ID"
+ });
+ cardStore.createIndex("by-set", "Set");
+ cardStore.createIndex("by-element", "Element");
+ cardStore.createIndex("by-type", "Type");
+ cardStore.createIndex("by-cost", "Cost");
+ cardStore.createIndex("by-power", "Power");
+ cardStore.createIndex("by-rarity", "Rarity");
+ }
+ });
+}
diff --git a/src/mlpccg/set.ts b/src/mlpccg/set.ts
new file mode 100644
index 0000000..1609c17
--- /dev/null
+++ b/src/mlpccg/set.ts
@@ -0,0 +1,47 @@
+import { SetFile } from "./types";
+import { openCardDB } from "./database";
+
+const baseURL = "https://mcg.zyg.ovh/setdata/";
+const allSets = [
+ "PR",
+ "CN",
+ "RR",
+ "CS",
+ "CG",
+ "AD",
+ "EO",
+ "HM",
+ "MT",
+ "DE",
+ "SB",
+ "FF",
+ "Promo"
+];
+
+export async function loadSets() {
+ const db = await openCardDB();
+ const itemcount = await db.count("card");
+ if (itemcount > 100) {
+ // DB already filled, exit early
+ return;
+ }
+ const sets = await Promise.all(allSets.map(set => downloadSet(set)));
+ await Promise.all(
+ sets.map(
+ async set =>
+ await Promise.all(
+ set.Cards.map(async card => await db.put("card", card))
+ )
+ )
+ );
+}
+
+async function downloadSet(setid: string): Promise {
+ const setfile = await fetch(`${baseURL}${setid.toLowerCase()}.json`);
+ const setdata: SetFile = await setfile.json();
+ setdata.Cards = setdata.Cards.map(c => {
+ c.Set = setid;
+ return c;
+ });
+ return setdata;
+}
diff --git a/src/mlpccg/types.ts b/src/mlpccg/types.ts
new file mode 100644
index 0000000..e879ba6
--- /dev/null
+++ b/src/mlpccg/types.ts
@@ -0,0 +1,28 @@
+export type Rarity = "C" | "U" | "R" | "SR" | "UR" | "RR";
+
+export type PowerRequirement = { [key: string]: number };
+
+export interface SetFile {
+ Name: string;
+ Cards: Card[];
+}
+
+export interface Card {
+ ID: string;
+ Set: string;
+ Name: string;
+ Subname: string;
+ Element: string[];
+ Keywords: string[];
+ Traits: string[];
+ Requirement?: PowerRequirement;
+ Cost?: number;
+ Power?: number;
+ Type: string;
+ Text: string;
+ Rarity: Rarity;
+ ProblemBonus?: number;
+ ProblemOpponentPower?: number;
+ ProblemRequirement?: PowerRequirement;
+ Boosted?: Card;
+}
diff --git a/src/store/actions.ts b/src/store/actions.ts
new file mode 100644
index 0000000..bc6cf05
--- /dev/null
+++ b/src/store/actions.ts
@@ -0,0 +1,18 @@
+import { ActionTree } from "vuex";
+import { AppState } from "./types";
+
+const actions: ActionTree = {
+ showLoading({ commit }, message: string) {
+ commit("setLoading", message);
+ },
+
+ hideLoading({ commit }) {
+ commit("setLoading", "");
+ },
+
+ setLoaded({ commit }, loaded: boolean) {
+ commit("setLoaded", loaded);
+ }
+};
+
+export default actions;
diff --git a/src/store/getters.ts b/src/store/getters.ts
new file mode 100644
index 0000000..b171a4e
--- /dev/null
+++ b/src/store/getters.ts
@@ -0,0 +1,17 @@
+import { GetterTree } from "vuex";
+import { AppState } from "./types";
+
+const getters: GetterTree = {
+ loaded(state): boolean {
+ return state.loaded;
+ },
+
+ loading(state): string | null {
+ if (state.loading) {
+ return state.loadingMessage;
+ }
+ return null;
+ }
+};
+
+export default getters;
diff --git a/src/store/index.ts b/src/store/index.ts
index 7273841..4909137 100644
--- a/src/store/index.ts
+++ b/src/store/index.ts
@@ -4,8 +4,19 @@ import { AppState } from "./types";
Vue.use(Vuex);
+import actions from "./actions";
+import mutations from "./mutations";
+import getters from "./getters";
+
const store: StoreOptions = {
- state: {},
+ state: {
+ loaded: false,
+ loading: false,
+ loadingMessage: ""
+ },
+ actions,
+ mutations,
+ getters,
modules: {}
};
diff --git a/src/store/mutations.ts b/src/store/mutations.ts
new file mode 100644
index 0000000..c0473e7
--- /dev/null
+++ b/src/store/mutations.ts
@@ -0,0 +1,15 @@
+import { MutationTree } from "vuex";
+import { AppState } from "./types";
+
+const mutations: MutationTree = {
+ setLoaded(state, loaded: boolean) {
+ state.loaded = loaded;
+ },
+
+ setLoading(state, message: string) {
+ state.loading = message != "";
+ state.loadingMessage = message;
+ }
+};
+
+export default mutations;
diff --git a/src/store/types.ts b/src/store/types.ts
index 06e2c2e..04230b8 100644
--- a/src/store/types.ts
+++ b/src/store/types.ts
@@ -1 +1,5 @@
-export interface AppState {}
+export interface AppState {
+ loaded: boolean;
+ loading: boolean;
+ loadingMessage: string;
+}
diff --git a/yarn.lock b/yarn.lock
index 26cd863..7b5d3c5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4453,6 +4453,11 @@ icss-utils@^2.1.0:
dependencies:
postcss "^6.0.1"
+idb@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/idb/-/idb-4.0.4.tgz#f0c06f58bd78fe557e4de944fd6ba6a3240faa8e"
+ integrity sha512-ZYsaBSNub2yAnjvmRKudQlMIPqZQIefAOwNIPeXC+RLIeXYFc0UNQqONKNuQeBNf8oBOV5L75yJ9zFISjHVj4g==
+
ieee754@^1.1.4:
version "1.1.13"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
@@ -8814,6 +8819,11 @@ vue@^2.6.10:
resolved "https://registry.yarnpkg.com/vue/-/vue-2.6.10.tgz#a72b1a42a4d82a721ea438d1b6bf55e66195c637"
integrity sha512-ImThpeNU9HbdZL3utgMCq0oiMzAkt1mcgy3/E6zWC/G6AaQoeuFdsl9nDhTDU3X1R6FK7nsIUuRACVcjI+A2GQ==
+vuex-class@^0.3.2:
+ version "0.3.2"
+ resolved "https://registry.yarnpkg.com/vuex-class/-/vuex-class-0.3.2.tgz#c7e96a076c1682137d4d23a8dcfdc63f220e17a8"
+ integrity sha512-m0w7/FMsNcwJgunJeM+wcNaHzK2KX1K1rw2WUQf7Q16ndXHo7pflRyOV/E8795JO/7fstyjH3EgqBI4h4n4qXQ==
+
vuex@^3.0.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.1.1.tgz#0c264bfe30cdbccf96ab9db3177d211828a5910e"