Switch to Rust API. Migration from Arrays to Objects (API compatability)

This commit is contained in:
Neshura 2023-08-27 21:00:56 +02:00
parent 40dee1e8f8
commit 05c3d3d6ec
Signed by: Neshura
GPG key ID: B6983AAA6B9A7A6C
9 changed files with 84 additions and 67 deletions

View file

@ -2,9 +2,9 @@ import { writable, type Writable } from "svelte/store";
export type SelectedChellarisGroups = { export type SelectedChellarisGroups = {
gameId: number, gameId: number,
selectedGroups: Array<number>, selectedGroups: { [key: number]: number },
} }
const SelectedGameGroupsStore: Writable<Array<SelectedChellarisGroups>> = writable([]); // Key should always be the same as gameId const SelectedGameGroupsStore: Writable<{ [key: number]: SelectedChellarisGroups }> = writable([]); // Key should always be the same as gameId
export default SelectedGameGroupsStore; export default SelectedGameGroupsStore;

View file

@ -1,15 +1,16 @@
import type { Ethic, Species } from './stellaris'; import type { Ethic, Species } from './stellaris';
export interface ChellarisInfo {
games: Array<ChellarisGame>, // Key is Game Id export type ChellarisInfo = {
ethics: Array<Ethic>, // Key is Ethic Id games: { [key: number]: ChellarisGame }, // Key is Game Id
species: Array<Species>, // Key is Species Group Id ethics: { [key: number]: Ethic }, // Key is Ethic Id
species: { [key: number]: Species }, // Key is Species Group Id
} }
export type ChellarisGame = { export type ChellarisGame = {
id: number, id: number,
name: string, name: string,
groups: Array<ChellarisGameGroup>, // Key is Group Id groups: { [key: number]: ChellarisGameGroup }, // Key is Group Id
empires: Array<ChellarisEmpire>, // Key is Empire Id empires: { [key: number]: ChellarisEmpire }, // Key is Empire Id
} }
export type ChellarisGameGroup = { export type ChellarisGameGroup = {
@ -25,7 +26,7 @@ export type ChellarisEmpire = {
empire_portrait: number, // TODO replace with Enum? empire_portrait: number, // TODO replace with Enum?
empire_portrait_group: number, // TODO replace with Enum? empire_portrait_group: number, // TODO replace with Enum?
discord_user?: string, discord_user?: string,
ethics: Array<Ethic>, ethics: { [key: number]: Ethic },
} }
export const createChellarisInfo = (): ChellarisInfo => { export const createChellarisInfo = (): ChellarisInfo => {

View file

@ -74,7 +74,7 @@ export type Ethic = {
export type Species = { export type Species = {
id: number, id: number,
displayName: string, displayName: string,
portraits: Array<Portrait>, // Key is Portrait Id portraits: { [key: number]: Portrait }, // Key is Portrait Id
} }
export type Portrait = { export type Portrait = {

View file

@ -37,7 +37,7 @@
</nav> </nav>
<div class="corner"> <div class="corner">
<a href="https://discord.gg/chellaris" target="_blank" rel="noopener noreferrer"> <a href="https://discord.gg/invite/BYNeHaPNh9" target="_blank" rel="noopener noreferrer">
<img src={discord} alt="Discord" /> <img src={discord} alt="Discord" />
</a> </a>
</div> </div>

View file

@ -5,15 +5,19 @@ import GraphsTabStore from '$lib/stores/GraphsTab';
import { createChellarisInfo, type ChellarisGame, createChellarisGame, createChellarisGameGroup, createChellarisEmpire } from "$lib/types/chellaris"; import { createChellarisInfo, type ChellarisGame, createChellarisGame, createChellarisGameGroup, createChellarisEmpire } from "$lib/types/chellaris";
import type { LayoutLoad } from "./$types"; import type { LayoutLoad } from "./$types";
import type { Ethic } from '../../lib/types/stellaris'; import type { Ethic } from '../../lib/types/stellaris';
import type { ChellarisInfo } from '../../lib/types/chellaris';
export const load: LayoutLoad = async ({ fetch }) => { export const load: LayoutLoad = async ({ fetch }) => {
let store: string | null; let store: string | null;
const apiBaseUrl = 'https://www.chellaris.net/api/v2'; const apiBaseUrl = 'https://wip.chellaris.net/api';
const chellarisData = createChellarisInfo(); const chellarisData = createChellarisInfo();
// Chellaris Data Code // Chellaris Data Code
const games: { id: number, name: string }[] = await (await fetch(apiBaseUrl + '/games')).json(); const data: ChellarisInfo = await (await fetch(apiBaseUrl + '/v3/full_view_data')).json();
const start = new Date(); // DEBUG
const games: { id: number, name: string }[] = await (await fetch(apiBaseUrl + '/v2/games')).json();
games.sort((a, b) => (a.name < b.name ? -1 : 1)); games.sort((a, b) => (a.name < b.name ? -1 : 1));
games.forEach(game => { games.forEach(game => {
@ -23,7 +27,7 @@ export const load: LayoutLoad = async ({ fetch }) => {
chellarisData.games[game.id] = newGame; chellarisData.games[game.id] = newGame;
}); });
const groups: { id: number, name: string, game_id: number }[] = await (await fetch(apiBaseUrl + '/game_groups')).json(); const groups: { id: number, name: string, game_id: number }[] = await (await fetch(apiBaseUrl + '/v2/game_groups')).json();
groups.sort((a, b) => (a.name < b.name ? -1 : 1)); groups.sort((a, b) => (a.name < b.name ? -1 : 1));
groups.forEach(group => { groups.forEach(group => {
@ -45,7 +49,7 @@ export const load: LayoutLoad = async ({ fetch }) => {
empire_portrait_id: number, empire_portrait_id: number,
empire_portrait_group_id: number, empire_portrait_group_id: number,
group_game_id: number group_game_id: number
}[] = await (await fetch(apiBaseUrl + '/empires')).json(); }[] = await (await fetch(apiBaseUrl + '/v2/empires')).json();
empires.sort((a, b) => (a.id < b.id ? -1 : 1)); empires.sort((a, b) => (a.id < b.id ? -1 : 1));
empires.forEach(empire => { empires.forEach(empire => {
@ -57,7 +61,7 @@ export const load: LayoutLoad = async ({ fetch }) => {
} }
}); });
const ethics: { id: number, name: string, machine_ethic: boolean }[] = await (await fetch(apiBaseUrl + '/ethics')).json(); const ethics: { id: number, name: string, machine_ethic: boolean }[] = await (await fetch(apiBaseUrl + '/v2/ethics')).json();
ethics.sort((a, b) => (a.id < b.id ? -1 : 1)); ethics.sort((a, b) => (a.id < b.id ? -1 : 1));
ethics.forEach(ethic => { ethics.forEach(ethic => {
@ -72,7 +76,7 @@ export const load: LayoutLoad = async ({ fetch }) => {
empires_group_game_id: number, empires_group_game_id: number,
ethics_id: number, ethics_id: number,
ethics_fanatic: boolean ethics_fanatic: boolean
}[] = await (await fetch(apiBaseUrl + '/empire_ethics')).json(); }[] = await (await fetch(apiBaseUrl + '/v2/empire_ethics')).json();
empireEthics.forEach(empireEthic => { empireEthics.forEach(empireEthic => {
const gameData = chellarisData.games[empireEthic.empires_group_game_id]; const gameData = chellarisData.games[empireEthic.empires_group_game_id];
@ -93,7 +97,7 @@ export const load: LayoutLoad = async ({ fetch }) => {
const portraitGroups: { const portraitGroups: {
id: number, id: number,
name: string name: string
}[] = await (await fetch(apiBaseUrl + '/portrait_groups')).json(); }[] = await (await fetch(apiBaseUrl + '/v2/portrait_groups')).json();
portraitGroups.sort((a, b) => (a.id < b.id ? -1 : 1)); portraitGroups.sort((a, b) => (a.id < b.id ? -1 : 1));
@ -107,7 +111,7 @@ export const load: LayoutLoad = async ({ fetch }) => {
hires: string, hires: string,
lores: string, lores: string,
group_id: number group_id: number
}[] = await (await fetch(apiBaseUrl + '/portraits')).json(); }[] = await (await fetch(apiBaseUrl + '/v2/portraits')).json();
portraits.sort((a, b) => (a.id < b.id ? -1 : 1)); portraits.sort((a, b) => (a.id < b.id ? -1 : 1));
@ -121,7 +125,10 @@ export const load: LayoutLoad = async ({ fetch }) => {
} }
}) })
ChellarisDataStore.set(chellarisData); console.log(new Date().getTime() - start.getTime(), "ms"); // DEBUG
console.log(data); // DEBUG
ChellarisDataStore.set(data);
// Local Storage Code // Local Storage Code
let gameGroupSelections: Array<SelectedChellarisGroups> = []; let gameGroupSelections: Array<SelectedChellarisGroups> = [];
@ -153,7 +160,7 @@ export const load: LayoutLoad = async ({ fetch }) => {
if (typeof gameGroupSelections[gameSelection] === 'undefined') { if (typeof gameGroupSelections[gameSelection] === 'undefined') {
// Default to all available groups // Default to all available groups
gameGroupSelections[gameSelection] = { gameId: gameSelection, selectedGroups: chellarisData.games[gameSelection].groups.map(group => group.id) }; gameGroupSelections[gameSelection] = { gameId: gameSelection, selectedGroups: Object.values(chellarisData.games[gameSelection].groups).map((group) => group.id) };
// Set Local Storage to default Values if not previously defined // Set Local Storage to default Values if not previously defined
localStorage.setItem('gameGroupSelection', JSON.stringify(gameGroupSelections)); localStorage.setItem('gameGroupSelection', JSON.stringify(gameGroupSelections));
@ -182,7 +189,7 @@ export const load: LayoutLoad = async ({ fetch }) => {
if (typeof gameGroupSelections[gameSelection] === 'undefined') { if (typeof gameGroupSelections[gameSelection] === 'undefined') {
// Default to all available groups // Default to all available groups
gameGroupSelections[gameSelection] = { gameId: gameSelection, selectedGroups: chellarisData.games[gameSelection].groups.map(group => group.id) }; gameGroupSelections[gameSelection] = { gameId: gameSelection, selectedGroups: Object.values(chellarisData.games[gameSelection].groups).map((group) => group.id) };
} }
SelectedGameGroupsStore.set(gameGroupSelections); SelectedGameGroupsStore.set(gameGroupSelections);

View file

@ -9,7 +9,7 @@
SelectedGameStore.subscribe((selection) => { SelectedGameStore.subscribe((selection) => {
if (typeof $SelectedGameGroupsStore[selection] === 'undefined') { if (typeof $SelectedGameGroupsStore[selection] === 'undefined') {
// Default to all available groups // Default to all available groups
$SelectedGameGroupsStore[selection] = { gameId: $SelectedGameStore, selectedGroups: $ChellarisDataStore.games[$SelectedGameStore].groups.map((group) => group.id) }; $SelectedGameGroupsStore[selection] = { gameId: $SelectedGameStore, selectedGroups: Object.values($ChellarisDataStore.games[$SelectedGameStore].groups).map((group) => group.id) };
SelectedGameGroupsStore.update(() => $SelectedGameGroupsStore); SelectedGameGroupsStore.update(() => $SelectedGameGroupsStore);
} }
}) })
@ -22,7 +22,7 @@
} }
$: selectedGameData = $SelectedGameGroupsStore[$SelectedGameStore]; $: selectedGameData = $SelectedGameGroupsStore[$SelectedGameStore];
$: groupJoiner = selectedGameData.selectedGroups.length > 2 ? ', ' : ' & '; $: groupJoiner = Object.values(selectedGameData.selectedGroups).length > 2 ? ', ' : ' & ';
const updateGroupStore = () => { const updateGroupStore = () => {
SelectedGameGroupsStore.update(() => $SelectedGameGroupsStore); SelectedGameGroupsStore.update(() => $SelectedGameGroupsStore);
@ -33,12 +33,12 @@
<DropDown <DropDown
{dropdownId} {dropdownId}
dropdownTitle={(selectedGameData.selectedGroups.length > 1 ? 'Groups ' : 'Group ') + dropdownTitle={(Object.values(selectedGameData.selectedGroups).length > 1 ? 'Groups ' : 'Group ') +
selectedGameData.selectedGroups Object.values(selectedGameData.selectedGroups)
.map((selection) => $ChellarisDataStore.games[$SelectedGameStore].groups[selection]?.name) .map((selection) => $ChellarisDataStore.games[$SelectedGameStore].groups[selection]?.name)
.join(groupJoiner)} .join(groupJoiner)}
> >
{#each $ChellarisDataStore.games[$SelectedGameStore].groups as group} {#each Object.values($ChellarisDataStore.games[$SelectedGameStore].groups) as group}
{#if group} {#if group}
<DropDownElement {dropdownId}> <DropDownElement {dropdownId}>
<input <input

View file

@ -16,7 +16,7 @@
</script> </script>
<DropDown {dropdownId} dropdownTitle={$ChellarisDataStore.games[$SelectedGameStore]?.name}> <DropDown {dropdownId} dropdownTitle={$ChellarisDataStore.games[$SelectedGameStore]?.name}>
{#each $ChellarisDataStore.games as game} {#each Object.values($ChellarisDataStore.games) as game}
<DropDownElement {dropdownId}> <DropDownElement {dropdownId}>
<input <input
id={'checkbox' + game.id} id={'checkbox' + game.id}

View file

@ -8,31 +8,35 @@
$: selectedGame = $ChellarisDataStore.games[$SelectedGameStore]; $: selectedGame = $ChellarisDataStore.games[$SelectedGameStore];
$: selectedGameGroupData = $SelectedGameGroupsStore[$SelectedGameStore]; $: selectedGameGroupData = $SelectedGameGroupsStore[$SelectedGameStore];
$: groupNoun = selectedGameGroupData.selectedGroups.length > 1 ? 'Groups' : 'Group'; $: groupNoun = Object.entries(selectedGameGroupData.selectedGroups).length > 1 ? 'Groups' : 'Group';
$: groupJoiner = selectedGameGroupData.selectedGroups.length > 2 ? ', ' : ' & '; $: groupJoiner = Object.entries(selectedGameGroupData.selectedGroups).length > 2 ? ', ' : ' & ';
let groupPortraitLimit: number; let groupPortraitLimit: number;
$: { $: {
let containsNA = false; let containsNA = false;
selectedGameGroupData.selectedGroups.forEach((selection) => { Object.values(selectedGameGroupData.selectedGroups).forEach((selection) => {
if ($ChellarisDataStore.games[$SelectedGameStore].groups[selection]?.name == 'N/A') { if ($ChellarisDataStore.games[$SelectedGameStore].groups[selection]?.name == 'N/A') {
containsNA = true; containsNA = true;
} }
}); });
groupPortraitLimit = containsNA ? $ChellarisDataStore.games[$SelectedGameStore].groups.length - 1 : selectedGameGroupData.selectedGroups.length; groupPortraitLimit = containsNA
? Object.entries($ChellarisDataStore.games[$SelectedGameStore].groups).length - 1
: Object.entries(selectedGameGroupData.selectedGroups).length;
} }
let pageData: { let pageData: {
init: boolean; init: boolean;
empireCount: number; empireCount: number;
gestaltCount: { total: number; machines: number }; gestaltCount: { total: number; machines: number };
ethicsData: Array<{ ethicsData: {
id: number; [key: number]: {
machine: boolean; id: number;
displayName: string; machine: boolean;
regular: number; displayName: string;
fanatic: number; regular: number;
}>; fanatic: number;
};
};
takenPortraits: Array<Array<[number, Array<number>]>>; // <SpeciesGroup, <Portrait, <SumTaken, <GroupsTaken>>>> takenPortraits: Array<Array<[number, Array<number>]>>; // <SpeciesGroup, <Portrait, <SumTaken, <GroupsTaken>>>>
}; };
$: { $: {
@ -42,25 +46,27 @@
init: boolean; init: boolean;
empireCount: number; empireCount: number;
gestaltCount: { total: number; machines: number }; gestaltCount: { total: number; machines: number };
ethicsData: Array<{ ethicsData: {
id: number; [key: number]: {
machine: boolean; id: number;
displayName: string; machine: boolean;
regular: number; displayName: string;
fanatic: number; regular: number;
}>; fanatic: number;
};
};
takenPortraits: Array<Array<[number, Array<number>]>>; // <SpeciesGroup, <Portrait, <SumTaken, <GroupsTaken>>>> takenPortraits: Array<Array<[number, Array<number>]>>; // <SpeciesGroup, <Portrait, <SumTaken, <GroupsTaken>>>>
} = { } = {
init: false, init: false,
empireCount: 0, empireCount: 0,
gestaltCount: { total: 0, machines: 0 }, gestaltCount: { total: 0, machines: 0 },
ethicsData: [], ethicsData: {},
takenPortraits: [] takenPortraits: []
}; };
if (selectedGame) { if (selectedGame) {
// Empty init of Ethics Data // Empty init of Ethics Data
$ChellarisDataStore.ethics.forEach((ethic) => { Object.values($ChellarisDataStore.ethics).forEach((ethic) => {
const newEthicsData: { const newEthicsData: {
id: number; id: number;
machine: boolean; machine: boolean;
@ -77,15 +83,15 @@
newPageData.ethicsData[ethic.id] = newEthicsData; newPageData.ethicsData[ethic.id] = newEthicsData;
}); });
selectedGame.empires.forEach((empire, index) => { Object.values(selectedGame.empires).forEach((empire, index) => {
if (selectedGameGroupData.selectedGroups.includes(empire.group)) { if (Object.values(selectedGameGroupData.selectedGroups).includes(empire.group)) {
newPageData.empireCount = newPageData.empireCount + 1; newPageData.empireCount = newPageData.empireCount + 1;
if (empire.gestalt) { if (empire.gestalt) {
newPageData.gestaltCount.total = newPageData.gestaltCount.total + 1; newPageData.gestaltCount.total = newPageData.gestaltCount.total + 1;
let machine = false; let machine = false;
empire.ethics.forEach((ethic) => { Object.values(empire.ethics).forEach((ethic) => {
if (ethic.machine) { if (ethic.machine) {
machine = true; machine = true;
} }
@ -96,8 +102,8 @@
} }
} }
empire.ethics.forEach((ethic, id) => { Object.values(empire.ethics).forEach((ethic) => {
const tmpEthicPageData = newPageData.ethicsData[id]; const tmpEthicPageData = newPageData.ethicsData[ethic.id];
if (typeof tmpEthicPageData !== 'undefined') { if (typeof tmpEthicPageData !== 'undefined') {
tmpEthicPageData.displayName = ethic.displayName; tmpEthicPageData.displayName = ethic.displayName;
@ -107,7 +113,7 @@
tmpEthicPageData.fanatic = tmpEthicPageData.fanatic + 1; tmpEthicPageData.fanatic = tmpEthicPageData.fanatic + 1;
} }
newPageData.ethicsData[id] = tmpEthicPageData; newPageData.ethicsData[ethic.id] = tmpEthicPageData;
} else { } else {
let newEthicsData: { let newEthicsData: {
id: number; id: number;
@ -129,7 +135,7 @@
newEthicsData.fanatic = 1; newEthicsData.fanatic = 1;
} }
newPageData.ethicsData[id] = newEthicsData; newPageData.ethicsData[ethic.id] = newEthicsData;
} }
}); });
@ -156,12 +162,12 @@
}); });
// Fill undefined Portrait Info with default information. // Fill undefined Portrait Info with default information.
for (let i = 0; i < $ChellarisDataStore.species.length; i++) { for (let i = 0; i < Object.values($ChellarisDataStore.species).length; i++) {
if (typeof newPageData.takenPortraits[i] === 'undefined') { if (typeof newPageData.takenPortraits[i] === 'undefined') {
newPageData.takenPortraits[i] = []; newPageData.takenPortraits[i] = [];
} }
for (let ii = 0; ii < $ChellarisDataStore.species[i].portraits.length; ii++) { for (let ii = 0; ii < Object.values($ChellarisDataStore.species[i].portraits).length; ii++) {
if (typeof newPageData.takenPortraits[i][ii] === 'undefined') { if (typeof newPageData.takenPortraits[i][ii] === 'undefined') {
newPageData.takenPortraits[i][ii] = [0, []]; newPageData.takenPortraits[i][ii] = [0, []];
} }
@ -172,6 +178,7 @@
} }
pageData = newPageData; pageData = newPageData;
console.log(pageData); // DEBUG
} }
// Save Tab to Store // Save Tab to Store
@ -186,7 +193,9 @@
{#if pageData.init} {#if pageData.init}
<h1> <h1>
{selectedGame.name} Sign-Up Info for {groupNoun} {selectedGame.name} Sign-Up Info for {groupNoun}
{selectedGameGroupData.selectedGroups.map((selection) => $ChellarisDataStore.games[$SelectedGameStore].groups[selection]?.name).join(groupJoiner)} {Object.values(selectedGameGroupData.selectedGroups)
.map((selection) => $ChellarisDataStore.games[$SelectedGameStore].groups[selection]?.name)
.join(groupJoiner)}
</h1> </h1>
<div class="text-column"> <div class="text-column">
@ -201,7 +210,7 @@
<th># Regular</th> <th># Regular</th>
<th># Fanatic</th> <th># Fanatic</th>
</tr> </tr>
{#each pageData.ethicsData as ethicData} {#each Object.values(pageData.ethicsData) as ethicData}
{#if ethicData && !ethicData.machine} {#if ethicData && !ethicData.machine}
<tr> <tr>
<td class="table-label">{ethicData.displayName}</td> <td class="table-label">{ethicData.displayName}</td>
@ -221,7 +230,7 @@
<th>Machine Ethic</th> <th>Machine Ethic</th>
<th>#</th> <th>#</th>
</tr> </tr>
{#each pageData.ethicsData as ethicData} {#each Object.values(pageData.ethicsData) as ethicData}
{#if ethicData && ethicData.machine} {#if ethicData && ethicData.machine}
<tr> <tr>
<td class="table-label">{ethicData.displayName}</td> <td class="table-label">{ethicData.displayName}</td>
@ -241,11 +250,11 @@
<th>{index + 1}</th> <th>{index + 1}</th>
{/each} {/each}
</tr> </tr>
{#each $ChellarisDataStore.species ?? false as portraitGroup} {#each Object.values($ChellarisDataStore.species) ?? false as portraitGroup}
{#if portraitGroup} {#if portraitGroup}
<tr> <tr>
<td>{portraitGroup.displayName}</td> <td>{portraitGroup.displayName}</td>
{#each portraitGroup.portraits ?? false as portrait} {#each Object.values(portraitGroup.portraits) ?? false as portrait}
{#if portrait} {#if portrait}
<td <td
class="image-box" class="image-box"

View file

@ -8,7 +8,7 @@
GraphsTabStore.update(() => 'tab'); GraphsTabStore.update(() => 'tab');
$: selectedGroups = $SelectedGameGroupsStore[$SelectedGameStore].selectedGroups; $: selectedGroups = $SelectedGameGroupsStore[$SelectedGameStore].selectedGroups;
$: groupJoiner = selectedGroups.length > 2 ? ', ' : ' & '; $: groupJoiner = Object.values(selectedGroups).length > 2 ? ', ' : ' & ';
</script> </script>
<svelte:head> <svelte:head>
@ -19,7 +19,7 @@
<h1>Example Tab</h1> <h1>Example Tab</h1>
<p> <p>
{selectedGroups.length > 1 ? 'Groups' : 'Group'} {Object.values(selectedGroups).length > 1 ? 'Groups' : 'Group'}
{selectedGroups.map((selection) => $ChellarisDataStore.games[$SelectedGameStore].groups[selection]?.name).join(groupJoiner)} {Object.values(selectedGroups).map((selection) => $ChellarisDataStore.games[$SelectedGameStore].groups[selection]?.name).join(groupJoiner)}
{selectedGroups.length > 1 ? 'are' : 'is'} selected {Object.values(selectedGroups).length > 1 ? 'are' : 'is'} selected
</p> </p>