Skip to content

Commit

Permalink
cubeview now loads list from scryfall while waiting for initial datab…
Browse files Browse the repository at this point in the history
…ase load
  • Loading branch information
dsoskey committed May 18, 2024
1 parent 4301594 commit ee6c8b0
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 20 deletions.
53 changes: 45 additions & 8 deletions src/api/local/useCogDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { createContext, SetStateAction, useRef, useState } from 'react'
import { Setter, TaskStatus } from '../../types'
import { cogDB, isScryfallManifest, Manifest } from './db'
import { migrateCubes, putFile } from './populate'
import { NormedCard, isOracleVal } from 'mtgql'
import { NormedCard, isOracleVal, normCardList } from 'mtgql'
import { QueryReport, useReporter } from '../useReporter'
import _isFunction from 'lodash/isFunction'
import { useLocalStorage } from './useLocalStorage'
import { defaultPromise } from '../context'
import { CubeCard } from 'mtgql/build/types/cube'
import * as Scryfall from 'scryfall-sdk'

export const DB_LOAD_MESSAGES = [
"loading cubes",
Expand Down Expand Up @@ -38,6 +40,7 @@ export interface CogDB {
memory: NormedCard[]
cardByOracle: (id: string) => NormedCard | undefined
bulkCardByOracle: (oracleIds: string[]) => Promise<NormedCard[]>
bulkCardByCubeList: (cards: CubeCard[]) => Promise<NormedCard[]>
setMemory: Setter<NormedCard[]>
loadFilter: string
setLoadFilter: Setter<string>
Expand All @@ -59,6 +62,7 @@ const defaultDB: CogDB = {
return undefined
},
bulkCardByOracle: defaultPromise("CogDB.bulkCardByOracle"),
bulkCardByCubeList: defaultPromise("CogDB.bulkCardByCubeList"),
dbReport: null,
setMemory: () => console.error("CogDB.setMemory called without a provider!"),
cardByName: () => {
Expand Down Expand Up @@ -307,21 +311,53 @@ export const useCogDB = (): CogDB => {
const missingMemoryIndices = memOracles
.map((card, index) => card === undefined ? index : -1)
.filter(index => index !== -1)
if (missingMemoryIndices.length === 0) return memOracles;

if (missingMemoryIndices.length) {
const oraclesToCheckDB = missingMemoryIndices.map(index => oracleIds[index]);
const newOracles = (await cogDB.card.bulkGet(oraclesToCheckDB)) ?? [];
const missingIndexes = newOracles
.map((card, index) => card === undefined ? index : -1)
.filter(index => index !== -1)
if (missingIndexes.length) return Promise.reject(missingIndexes);
const oraclesToCheckDB = missingMemoryIndices.map(index => oracleIds[index]);
const newOracles = (await cogDB.card.bulkGet(oraclesToCheckDB)) ?? [];
const missingIndexes = newOracles
.map((card, index) => card === undefined ? index : -1)
.filter(index => index !== -1)

if (missingIndexes.length) return Promise.reject(missingIndexes);

for (let i = 0; i < missingMemoryIndices.length; i++){
const index = missingMemoryIndices[i]
memOracles[index] = newOracles[i]
}
return memOracles
}

const bulkCardByCubeList = async (cubeList: CubeCard[]) => {
const memOracles = cubeList.map(it => cardByOracle(it.oracle_id))
const missingMemoryIndices = memOracles
.map((card, index) => card === undefined ? index : -1)
.filter(index => index !== -1)
if (missingMemoryIndices.length === 0) return memOracles;

const oraclesToCheckDB = missingMemoryIndices.map(index => cubeList[index].oracle_id);
const newOracles = (await cogDB.card.bulkGet(oraclesToCheckDB)) ?? [];
const missingDBIndexes = newOracles
.map((card, index) => card === undefined ? index : -1)
.filter(index => index !== -1)

if (missingDBIndexes.length === 0) {
for (let i = 0; i < missingMemoryIndices.length; i++){
const index = missingMemoryIndices[i]
memOracles[index] = newOracles[i]
}
return memOracles
}

const toCheckScryfall = missingDBIndexes
.map(index => Scryfall.CardIdentifier.byId(cubeList[index].print_id));
const scryfallCards = await Scryfall.Cards.collection(...toCheckScryfall).waitForAll();
if (scryfallCards.not_found.length) return Promise.reject(scryfallCards.not_found);

for (let i = 0; i < missingDBIndexes.length; i++){
const index = missingDBIndexes[i]
memOracles[index] = normCardList([scryfallCards[i]])[0];
}
return memOracles
}

Expand All @@ -334,6 +370,7 @@ export const useCogDB = (): CogDB => {
memory,
cardByOracle,
bulkCardByOracle,
bulkCardByCubeList,
setMemory,
resetDB,
loadManifest,
Expand Down
2 changes: 2 additions & 0 deletions src/api/local/useProjectDao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ export function useProjectDao(): ProjectDao {
}

const moveProject = async (oldPath: string, newPath: string) => {
if (oldPath === newPath) throw Error("can't move path to itself")
if (oldPath === initialPath) {
await saveMemory();
}
Expand All @@ -242,6 +243,7 @@ export function useProjectDao(): ProjectDao {
}

const moveFolder = async (oldPath: string, newPath: string) => {
if (oldPath === newPath) throw Error("can't move path to itself")
if (initialPath.startsWith(oldPath)) {
await saveMemory();
}
Expand Down
25 changes: 13 additions & 12 deletions src/ui/cubeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { Multiselect } from './component/multiselect'
import { useLocalStorage } from '../api/local/useLocalStorage'
import { Link, useSearchParams } from 'react-router-dom'
import { CopyToClipboardButton } from './component/copyToClipboardButton'
import { DBStatusLoader } from './component/dbStatusLoader'
import { CogDBContext } from '../api/local/useCogDB'
import { CardsPerRowControl } from './component/cardsPerRowControl'
import { useViewportListener } from './viewport'
Expand Down Expand Up @@ -76,7 +75,7 @@ function LoadingError({ cardCount, refreshCubeCards }) {
}
export function CubeView() {
const { key } = useParams();
const { dbStatus, bulkCardByOracle } = useContext(CogDBContext);
const { dbStatus, bulkCardByOracle, bulkCardByCubeList } = useContext(CogDBContext);
const viewport = useViewportListener();
const [searchError, setSearchError] = useState<SearchError | undefined>()
const [loadingError, setLoadingError] = useState<React.ReactNode>(undefined);
Expand Down Expand Up @@ -112,26 +111,30 @@ export function CubeView() {

const refreshCubeCards = async () => {
try {
const next: OrderedCard[] = [];
const oracleIds = cube.cards?.map(it=>it.oracle_id) ?? cube.oracle_ids;
const newOracles = await bulkCardByOracle(oracleIds);
const byOracle = _groupBy(newOracles, "oracle_id");
setOracles(byOracle);
if (needsMigration) {
const newOracles = await bulkCardByOracle(cube.oracle_ids);
const byOracle = _groupBy(newOracles, "oracle_id");
setOracles(byOracle);

const cards = newOracles.map(it => ({ oracle_id: it.oracle_id, print_id: it.printings[0].id }));
await cogDBClient.cube.put({
...cube,
cards
});
} else {
const newOracles = await bulkCardByCubeList(cube.cards);
const byOracle = _groupBy(newOracles, "oracle_id");
setOracles(byOracle);

const printToCard: { [key: string]: Card } = {};
for (const normCard of newOracles) {
for (const print of normCard.printings) {
printToCard[print.id] = {...normCard, ...print};
}
}

const missingPrints = []
const missingPrints = [];
const next: OrderedCard[] = [];
for (let i = 0; i < cube.cards.length; i++) {
const printId = cube.cards[i].print_id
if (printId in printToCard) {
Expand Down Expand Up @@ -167,7 +170,7 @@ export function CubeView() {
};

useEffect(() => {
if (cube && dbStatus === "success") refreshCubeCards().catch(console.error);
if (cube) refreshCubeCards().catch(console.error);
}, [cube, dbStatus])

const onPrintSelect = (e: React.ChangeEvent<HTMLSelectElement>) => {
Expand Down Expand Up @@ -248,10 +251,8 @@ export function CubeView() {
{cards.length === 0
&& searchError === undefined
&& loadingError === undefined
&& dbStatus !== "loading" &&
<LoaderText text="Loading cards"/>}
&& <LoaderText text="Loading cards"/>}
{loadingError}
{dbStatus === "loading" && <div className="cube-db-status"><DBStatusLoader /></div>}
</div>
{sorted.length > 0 && searchError === undefined && <div className='result-container'>
<div className="card-image-container">
Expand Down

0 comments on commit ee6c8b0

Please sign in to comment.