Skip to content

Commit

Permalink
upgrade mtgql to get new features & added wordcount sort to cubeList
Browse files Browse the repository at this point in the history
  • Loading branch information
dsoskey committed Jun 17, 2024
1 parent 28a8f60 commit 9a223a9
Show file tree
Hide file tree
Showing 10 changed files with 80 additions and 59 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"micromark-util-chunked": "^2.0.0",
"micromark-util-symbol": "^2.0.0",
"moo": "^0.5.2",
"mtgql": "^1.4.2",
"mtgql": "^1.5.0",
"nearley": "^2.20.1",
"neverthrow": "^6.0.0",
"prismjs": "^1.29.0",
Expand Down
9 changes: 8 additions & 1 deletion src/api/local/db.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Dexie, { Table } from 'dexie'
import { BulkDataDefinition } from 'scryfall-sdk/out/api/BulkData'
import { Block, Cube, DataProvider, IllustrationTag, NormedCard, OracleTag } from 'mtgql'
import { Block, CardSet, Cube, DataProvider, IllustrationTag, NormedCard, OracleTag } from 'mtgql'
import { DataSource } from '../../types'
import { Project } from './types/project'
import { RunStrategy } from '../queryRunnerCommon'
Expand Down Expand Up @@ -60,6 +60,7 @@ export class TypedDexie extends Dexie implements DataProvider {
oracleTag!: Table<OracleTag>
illustrationTag!: Table<IllustrationTag>
block!: Table<Block>
set!: Table<CardSet>
history!: Table<QueryHistory>
project!: Table<Project>
projectFolder!: Table<ProjectFolder>
Expand All @@ -77,6 +78,8 @@ export class TypedDexie extends Dexie implements DataProvider {
return it
})

getSet = (key: string) => this.set.get({ code: key })

getCardByNameId = async (name: string, id: string) => {
let res = await cogDB.card.where("name").equals(name).toArray();
if (res.length === 0)
Expand Down Expand Up @@ -219,6 +222,10 @@ export class TypedDexie extends Dexie implements DataProvider {
}
})
})

this.version(16).stores({
set: 'id, code, name'
})
}
}
export const cogDB = new TypedDexie()
Expand Down
13 changes: 7 additions & 6 deletions src/api/local/dbWorker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ async function initOfficialDB(type: BulkDataType, targets: ImportTarget[], filte

await loadOracleTags();
await loadIllustrationTags();
await loadBlocks();
await loadSetsAndBlocks();

let res;
if (manifest.filter) {
Expand Down Expand Up @@ -167,9 +167,10 @@ async function loadIllustrationTags() {
postMessage({ type: 'illustration-tag-end' })
}

async function loadBlocks() {
const sets = await downloadSets()
postMessage({ type: "blocks-downloaded", data: sets.length })
await cogDB.block.bulkPut(sets)
postMessage({ type: "blocks-end" })
async function loadSetsAndBlocks() {
const { blocks, sets } = await downloadSets()
postMessage({ type: "sets-downloaded", data: sets.length })
await cogDB.block.bulkPut(blocks)
await cogDB.set.bulkPut(sets)
postMessage({ type: "sets-end" })
}
4 changes: 2 additions & 2 deletions src/api/local/useCogDB.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,8 +194,8 @@ export const useCogDB = (): CogDB => {
case "oracle-tag-end":
case "illustration-tag-downloaded":
case "illustration-tag-end":
case "blocks-downloaded":
case "blocks-end":
case "sets-downloaded":
case "sets-end":
dbReport.addComplete()
break
case "normed-cards":
Expand Down
17 changes: 12 additions & 5 deletions src/api/scryfall/set.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Block } from 'mtgql'
import { Block, CardSet } from 'mtgql'

export async function downloadSets(): Promise<Block[]> {
export interface BulkSetInfo {
sets: CardSet[]
blocks: Block[]
}
export async function downloadSets(): Promise<BulkSetInfo> {
const response = await fetch("https://api.scryfall.com/sets")
const text = await response.text()
const jsoned = JSON.parse(text).data as any[];
const cardSets = JSON.parse(text).data as CardSet[];
const blocks: { [key: string]: Block } = {};
for (const c of jsoned) {
for (const c of cardSets) {
if (c.block_code !== undefined) {
if (blocks[c.block_code] === undefined) {
blocks[c.block_code] = {
Expand All @@ -18,5 +22,8 @@ export async function downloadSets(): Promise<Block[]> {
}
}
}
return Object.values(blocks)
return {
sets: cardSets,
blocks: Object.values(blocks),
}
}
28 changes: 9 additions & 19 deletions src/ui/cardBrowser/cardViews/searchHoverActions.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useContext, useState } from 'react'
import React, { useContext } from 'react'
import { ScryfallIcon } from '../../component/scryfallIcon'
import { FlagContext } from '../../flags'
import { EnrichedCard } from '../../../api/queryRunnerCommon'
import { TaskStatus } from '../../../types'
import { useCopyToClipboard } from '../../component/copyToClipboardButton'

const copyText = {
unstarted: '📑',
Expand All @@ -23,21 +23,7 @@ export interface SearchHoverActionsProps {
}
export function SearchHoverActions({ card, onAdd, onIgnore }: SearchHoverActionsProps) {
const { showDebugInfo } = useContext(FlagContext).flags
const [clipboardStatus, setClipboardStatus] =
useState<TaskStatus>('unstarted')
const copyToJson = () => {
navigator.clipboard
.writeText(JSON.stringify(card.data, undefined, 2))
.then(() => {
setClipboardStatus('success')
setTimeout(() => {
setClipboardStatus('unstarted')
}, 3000)
})
.catch(() => {
setClipboardStatus('error')
})
}
const clipboardHandler = useCopyToClipboard(() => JSON.stringify(card.data, undefined, 2))
return <div className='hover-actions'>
<a
href={card.data.scryfall_uri.replace(/\?.+$/, '')}
Expand All @@ -48,8 +34,12 @@ export function SearchHoverActions({ card, onAdd, onIgnore }: SearchHoverActions
<ScryfallIcon size='1em' />
</button>
</a>
{showDebugInfo && <button title={copyTitle[clipboardStatus]} onClick={copyToJson}>
{copyText[clipboardStatus]}
{showDebugInfo && <button
title={copyTitle[clipboardHandler.status]}
onClick={clipboardHandler.onClick}

>
{copyText[clipboardHandler.status]}
</button>}
<button title='ignore' onClick={onIgnore}>🚫</button>
<button title='add to list' onClick={onAdd}>
Expand Down
47 changes: 28 additions & 19 deletions src/ui/component/copyToClipboardButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
import React, { HTMLAttributes, useState } from 'react'
import { TaskStatus } from '../../types'
import _isFunction from 'lodash/isFunction'

export function useCopyToClipboard(copyText: (() => string) | string) {
const [status, setStatus] =
useState<TaskStatus>('unstarted')

const onClick = () => {
const text = _isFunction(copyText) ? copyText() : copyText;
navigator.clipboard
.writeText(text)
.then(() => {
setStatus('success')
setTimeout(() => {
setStatus('unstarted')
}, 3000)
})
.catch(() => {
setStatus('error')
})
}

return { onClick, status }
}

const DEFAULT_BUTTON_TEXT = {
unstarted: 'copy to clipboard',
Expand All @@ -14,33 +37,19 @@ interface CopyToClipboardButtonProps extends HTMLAttributes<HTMLButtonElement> {
className?: string
}
export const CopyToClipboardButton = ({ buttonText, copyText, className, children, ...rest }: CopyToClipboardButtonProps) => {
const [clipboardStatus, setClipboardStatus] =
useState<TaskStatus>('unstarted')

let content = DEFAULT_BUTTON_TEXT[clipboardStatus];
const { status, onClick } = useCopyToClipboard(copyText);
let content = DEFAULT_BUTTON_TEXT[status];
if (children) {
content = children
} else if (buttonText) {
content = buttonText[clipboardStatus]
content = buttonText[status]
}

return <button
{...rest}
className={className}
disabled={clipboardStatus !== 'unstarted'}
onClick={() => {
navigator.clipboard
.writeText(copyText)
.then(() => {
setClipboardStatus('success')
setTimeout(() => {
setClipboardStatus('unstarted')
}, 3000)
})
.catch(() => {
setClipboardStatus('error')
})
}}
disabled={status !== 'unstarted'}
onClick={onClick}
>
{content}
</button>
Expand Down
4 changes: 4 additions & 0 deletions src/ui/cubeView/cubeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ const orderValToKey = {
rarity: SortFunctions.byRarity,
edhrec: byEdhrecRank,
creatures_first: isCreature,
word_count: SortFunctions.byWordCount,
full_word_count: SortFunctions.byFullWordCount,
}

const SORT_OPTIONS = [
Expand All @@ -41,6 +43,8 @@ const SORT_OPTIONS = [
"released",
"rarity",
"edhrec",
"word_count",
"full_word_count"
]

const options: SearchOptions = {
Expand Down
7 changes: 5 additions & 2 deletions src/ui/cubeView/cubeView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Modal } from '../component/modal'
import { RefreshButton } from '../component/cube/refreshButton'
import { ScryfallIcon } from '../component/scryfallIcon'
import { LoaderText } from '../component/loaders'
import { CopyToClipboardButton } from '../component/copyToClipboardButton'
import { CopyToClipboardButton, useCopyToClipboard } from '../component/copyToClipboardButton'
import { CubeNotFoundView } from './notFoundView'
import {
CubeViewModelContext,
Expand All @@ -30,6 +30,7 @@ export function CubeView() {
const showDebugInfo = useContext(FlagContext).flags.showDebugInfo;
const cubeViewModel = useCubeViewModel();
const { cube, oracleMap, activeCard, setActiveCard } = cubeViewModel;
const clipboardHandler = useCopyToClipboard(() => JSON.stringify(activeCard, undefined, 2))

const onPrintSelect = (e: React.ChangeEvent<HTMLSelectElement>) => {
const normedCard = oracleMap[activeCard.oracle_id][0]
Expand Down Expand Up @@ -123,7 +124,9 @@ export function CubeView() {
<h3>status</h3>
<div>{activeCard.status}</div>

{showDebugInfo && <pre><code>{JSON.stringify(activeCard, undefined, 2)}</code></pre>}
{showDebugInfo && <pre onClick={clipboardHandler.onClick}>
<code>{JSON.stringify(activeCard, undefined, 2)}</code>
</pre>}
</div>
</div>}
</Modal>
Expand Down

0 comments on commit 9a223a9

Please sign in to comment.