diff --git a/interfaces/carddata.ts b/interfaces/carddata.ts index a6b8511..e225139 100644 --- a/interfaces/carddata.ts +++ b/interfaces/carddata.ts @@ -5,6 +5,10 @@ export interface ICard { name: string; tags: string[]; + product: string; + subproduct: string; + locale: string; + imageClass?: string; meta: Record; } diff --git a/interfaces/product.ts b/interfaces/product.ts index 7b76562..015b2ff 100644 --- a/interfaces/product.ts +++ b/interfaces/product.ts @@ -6,6 +6,7 @@ export interface IProductFilter { export interface IProductDefinition { id: string; name: string; + desc: string; } export interface IProduct extends IProductDefinition { diff --git a/search/operators/card.ts b/search/operators/card.ts index 8a4494f..cfaf176 100644 --- a/search/operators/card.ts +++ b/search/operators/card.ts @@ -1,37 +1,34 @@ import { type ICardHelp } from '../../interfaces'; import { partialWithOptionalExactTextOperator } from './_helpers'; -export const card = partialWithOptionalExactTextOperator( - ['card', 'id', 'code'], - 'id' -); +export const card = partialWithOptionalExactTextOperator(['card', 'id'], 'id'); export const cardDescription: ICardHelp = { - name: 'Code / ID', - id: 'code', + name: 'ID', + id: 'id', icon: 'finger-print-outline', color: '#8360c3', help: ` -You can find cards that match a certain code/id by using the \`id:\` operator. +You can find cards that match a certain id by using the \`id:\` operator. This operator is special, you may also search without using the operator. `, examples: [ { - example: '`5HY/W83-E001`', - explanation: 'Find specifically the card matching 5HY/W83-E001', + example: '`OATH/1`', + explanation: 'Find specifically the card matching OATH/1', }, { - example: '`id:=5HY/W83-E001`', - explanation: 'Find specifically the card matching 5HY/W83-E001.', + example: '`id:=OATH/1`', + explanation: 'Find specifically the card matching OATH/1.', }, { - example: '`-id:5HY/W83`', - explanation: 'Exclude the cards matching 5HY/W83.', + example: '`-id:OATH`', + explanation: 'Exclude the cards matching OATH.', }, ], }; diff --git a/search/operators/in.ts b/search/operators/in.ts deleted file mode 100644 index 5022027..0000000 --- a/search/operators/in.ts +++ /dev/null @@ -1,75 +0,0 @@ -import type * as parser from 'search-query-parser'; -import { type ICard, type ICardHelp } from '../../interfaces'; - -// this operator lets you check if something is in your collection, or not in your collection -export function inOperator(aliases: string[]) { - return ( - cards: ICard[], - results: parser.SearchParserResult, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - extraData: any = {} - ) => { - // if we have no cards, short-circuit because we can't filter it anymore - if (cards.length === 0) { - return []; - } - - // if this operator isn't present at all, we skip it - const shouldFilterThisOperator = aliases.some( - (alias) => results[alias] || results.exclude?.[alias] - ); - if (!shouldFilterThisOperator) { - return cards; - } - - const collection = extraData.collection ?? {}; - - // map all of the aliases (the same alias is an OR) - return aliases - .map((alias) => { - // collection filtering - if (results.exclude?.[alias] === 'collection') { - return cards.filter((c) => !collection[c.id]); - } - - if (results[alias] === 'collection') { - return cards.filter((c) => collection[c.id]); - } - - // if we have no results for this alias, we return no cards - return []; - }) - .flat(); - }; -} - -export const inC = inOperator(['in']); - -export const inDescription: ICardHelp = { - name: 'In', - id: 'in', - - icon: 'archive-outline', - - color: '#36abe0', - - help: ` -You can find cards that are either in or not in your collection by using the \`in:\` operator. - -Presently, you can only specify \`collection\` as the value for this operator. - -You can modify your collection by logging in -and then going to my collection. -`, - - examples: [ - { - example: '`in:collection`', - explanation: 'Cards in your collection.', - }, - { - example: '`-in:collection`', - explanation: 'Cards not in your collection.', - }, - ], -}; diff --git a/search/operators/index.ts b/search/operators/index.ts index 5647dcd..567f212 100644 --- a/search/operators/index.ts +++ b/search/operators/index.ts @@ -1,5 +1,6 @@ export * from './bare'; export * from './card'; -export * from './in'; export * from './name'; +export * from './product'; +export * from './subproduct'; export * from './tag'; diff --git a/search/operators/name.ts b/search/operators/name.ts index 90588ab..b3c0024 100644 --- a/search/operators/name.ts +++ b/search/operators/name.ts @@ -21,20 +21,20 @@ If a name has spaces in its name, you must use quotation marks around the name. examples: [ { - example: '`Nino Nakano`', - explanation: 'Cards with "Nino Nakano" in their name.', + example: '`Alchemist`', + explanation: 'Cards with "Alchemist" in their name.', }, { - example: '`name:nakano`', - explanation: 'Cards that have "Nakano" in their name.', + example: '`name:alchemist`', + explanation: 'Cards that have "alchemist" in their name.', }, { - example: '`name:"=Nino Nakano"`', - explanation: 'Cards that are called exactly "Nino Nakano".', + example: '`name:"=Alchemist"`', + explanation: 'Cards that are called exactly "Alchemist".', }, { - example: '`-name:"Futaro Uesugi"`', - explanation: 'Cards without "Futaro Uesugi" in their name.', + example: '`-name:"Alchemist"`', + explanation: 'Cards without "Alchemist" in their name.', }, ], }; diff --git a/search/operators/product.ts b/search/operators/product.ts new file mode 100644 index 0000000..70ab74b --- /dev/null +++ b/search/operators/product.ts @@ -0,0 +1,28 @@ +import { type ICardHelp } from '../../interfaces'; +import { exactTextOperator } from './_helpers'; + +export const product = exactTextOperator(['product', 'game'], 'product'); + +export const productDescription: ICardHelp = { + name: 'Product', + id: 'id', + + icon: 'game-controller-outline', + + color: '#d0312d', + + help: ` +You can find cards that are associated with a certain product/game by using the \`product:\` operator. +`, + + examples: [ + { + example: '`product:oath`', + explanation: 'Find cards belonging to Oath.', + }, + { + example: '`-product:root`', + explanation: 'Exclude the cards belonging to Root.', + }, + ], +}; diff --git a/search/operators/subproduct.ts b/search/operators/subproduct.ts new file mode 100644 index 0000000..402dbd2 --- /dev/null +++ b/search/operators/subproduct.ts @@ -0,0 +1,31 @@ +import { type ICardHelp } from '../../interfaces'; +import { exactTextOperator } from './_helpers'; + +export const subproduct = exactTextOperator( + ['subproduct', 'expansion'], + 'subproduct' +); + +export const subproductDescription: ICardHelp = { + name: 'Subproduct', + id: 'id', + + icon: 'hardware-chip-outline', + + color: '#ffa500', + + help: ` +You can find cards that are associated with a certain subproduct/expansion by using the \`subproduct:\` operator. +`, + + examples: [ + { + example: '`subproduct:clockwork-1`', + explanation: 'Find cards belonging to the first Clockwork expansion.', + }, + { + example: '`-subproduct:exiles-partisans`', + explanation: 'Exclude the cards belonging to Exiles & Partisans.', + }, + ], +}; diff --git a/search/operators/tag.ts b/search/operators/tag.ts index 0b45f75..87a0af1 100644 --- a/search/operators/tag.ts +++ b/search/operators/tag.ts @@ -18,12 +18,12 @@ Almost every card will have a tag. You can find a list of valid tags by using th examples: [ { - example: '`tag:"Army"`', - explanation: 'Cards that have the Army tag.', + example: '`tag:"Power"`', + explanation: 'Cards that have the Power tag.', }, { - example: '`tag:"Army,Clock Cleanset"`', - explanation: 'Cards that have the Army and Clock Cleanse triggers.', + example: '`tag:"Power,Arcane"`', + explanation: 'Cards that have the Power and Arcane triggers.', }, { example: '`tag:none`', diff --git a/search/search.ts b/search/search.ts index 31ef25a..ae1761a 100644 --- a/search/search.ts +++ b/search/search.ts @@ -4,16 +4,17 @@ import * as parser from 'search-query-parser'; import { type ICard } from '../interfaces'; -import { bare, card, inC, name, tag } from './operators'; +import { bare, card, name, product, subproduct, tag } from './operators'; const allKeywords = [ ['id'], // exact text - ['in'], // special operator ['name', 'n'], // loose text + ['product', 'game'], // exact text + ['subproduct', 'expansion'], // exact text ['tag'], // array search ]; -const operators = [inC, card, name, tag]; +const operators = [card, name, product, subproduct, tag]; export function properOperatorsInsteadOfAliases( result: parser.SearchParserResult @@ -48,18 +49,6 @@ const allQueryFormatters = [ return `${value}`; }, }, - { - key: 'expansion', - includes: 'has', - excludes: 'does not have', - formatter: (result: Record) => { - const value = result['expansion']; - const expansions: string[] = isString(value) - ? [value] - : (value as unknown as string[]); - return `${expansions.map((x) => `"${x}"`).join(' or ')}`; - }, - }, { key: 'name', includes: 'contains', @@ -70,11 +59,20 @@ const allQueryFormatters = [ }, }, { - key: 'set', + key: 'product', + includes: 'is', + excludes: 'is not', + formatter: (result: Record) => { + const value = result['product']; + return `${value}`; + }, + }, + { + key: 'subproduct', includes: 'is', excludes: 'is not', formatter: (result: Record) => { - const value = result['set']; + const value = result['subproduct']; return `${value}`; }, }, @@ -104,7 +102,7 @@ export function queryToText(query: string): string { .split(' ') .map((x) => `"${x}"`) .join(' or '); - return `cards with ${queries} in the name, abilities, expansion, or code`; + return `cards with ${queries} in the name or card id`; } const result = properOperatorsInsteadOfAliases(firstResult); diff --git a/src/app/_shared/components/search-cards/search-cards.component.html b/src/app/_shared/components/search-cards/search-cards.component.html index 3d5bcff..3f6b180 100644 --- a/src/app/_shared/components/search-cards/search-cards.component.html +++ b/src/app/_shared/components/search-cards/search-cards.component.html @@ -152,18 +152,8 @@

No results found

Name - Code - Rarity - Expansion - Side - Type - Color - Level - Cost - Power - Soul - Set - Release + ID + Product + + + +

{{ subproduct.desc }}

+
+
} diff --git a/src/app/sets/sets.page.ts b/src/app/sets/sets.page.ts index 6d35350..1d9eaf2 100644 --- a/src/app/sets/sets.page.ts +++ b/src/app/sets/sets.page.ts @@ -25,7 +25,7 @@ export class SetsPage implements OnInit { } formatSetNameForSearch(productId: string, subproductId: string): string { - return `game:"${productId}" expansion:"${subproductId}"`; + return `product:"${productId}" subproduct:"${subproductId}"`; } search(query: string) { diff --git a/src/app/syntax/syntax.page.ts b/src/app/syntax/syntax.page.ts index 4392fc1..950765e 100644 --- a/src/app/syntax/syntax.page.ts +++ b/src/app/syntax/syntax.page.ts @@ -8,8 +8,9 @@ import { type ICardHelp } from '../../../interfaces'; import { cardDescription, - inDescription, nameDescription, + productDescription, + subproductDescription, tagDescription, } from '../../../search/operators'; @@ -24,8 +25,9 @@ export class SyntaxPage implements OnInit { public allOperators: ICardHelp[] = [ cardDescription, - inDescription, nameDescription, + productDescription, + subproductDescription, tagDescription, ];