Moved to subfolder "query"
parent
2c9f8e2d0b
commit
3c34b63cb6
|
@ -1,114 +0,0 @@
|
||||||
// Public modules from npm
|
|
||||||
import validator from 'class-validator';
|
|
||||||
|
|
||||||
// Modules from file
|
|
||||||
import { urls } from "../constants/url.js";
|
|
||||||
import PrefixParser from './prefix-parser.js';
|
|
||||||
import { TCategory } from "../interfaces";
|
|
||||||
|
|
||||||
// Type definitions
|
|
||||||
type TSort = "date" | "likes" | "views" | "title" | "rating";
|
|
||||||
type TDate = 365 | 180 | 90 | 30 | 14 | 7 | 3 | 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query used to search for specific threads on the platform.
|
|
||||||
*/
|
|
||||||
export default class HandiworkSearchQuery {
|
|
||||||
|
|
||||||
//#region Private fields
|
|
||||||
private static MAX_TAGS = 5;
|
|
||||||
private static MIN_PAGE = 1;
|
|
||||||
//#endregion Private fields
|
|
||||||
|
|
||||||
//#region Properties
|
|
||||||
/**
|
|
||||||
* Category of items to search among.
|
|
||||||
* Default: `games`
|
|
||||||
*/
|
|
||||||
public category: TCategory = 'games';
|
|
||||||
/**
|
|
||||||
* List of IDs of tags to be included in the search.
|
|
||||||
* Max. 5 tags
|
|
||||||
*/
|
|
||||||
@validator.IsArray({
|
|
||||||
message: "Expected an array, received $value"
|
|
||||||
})
|
|
||||||
@validator.ArrayMaxSize(HandiworkSearchQuery.MAX_TAGS, {
|
|
||||||
message: "Too many tags: $value instead of $constraint1"
|
|
||||||
})
|
|
||||||
public tags: string[] = [];
|
|
||||||
/**
|
|
||||||
* List of IDs of prefixes to be included in the search.
|
|
||||||
*/
|
|
||||||
@validator.IsArray({
|
|
||||||
message: "Expected an array, received $value"
|
|
||||||
})
|
|
||||||
public prefixes: string[] = [];
|
|
||||||
/**
|
|
||||||
* Sorting type. Default: `date`.
|
|
||||||
*/
|
|
||||||
public sort: TSort = 'date';
|
|
||||||
/**
|
|
||||||
* Date limit in days, to be understood as "less than".
|
|
||||||
* Use `1` to indicate "today" or `null` to indicate "anytime".
|
|
||||||
* Default: `null`
|
|
||||||
*/
|
|
||||||
public date: TDate = null;
|
|
||||||
/**
|
|
||||||
* Index of the page to be obtained.
|
|
||||||
* Between 1 and infinity.
|
|
||||||
* Default: 1.
|
|
||||||
*/
|
|
||||||
@validator.IsInt({
|
|
||||||
message: "$property expect an integer, received $value"
|
|
||||||
})
|
|
||||||
@validator.Min(HandiworkSearchQuery.MIN_PAGE, {
|
|
||||||
message: "The minimum $property value must be $constraint1, received $value"
|
|
||||||
})
|
|
||||||
public page = HandiworkSearchQuery.MIN_PAGE;
|
|
||||||
//#endregion Properties
|
|
||||||
|
|
||||||
//#region Public methods
|
|
||||||
/**
|
|
||||||
* Verify that the query values are valid.
|
|
||||||
*/
|
|
||||||
public validate(): boolean {
|
|
||||||
return validator.validateSync(this).length === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* From the query values it generates the corresponding URL for the platform.
|
|
||||||
* If the query is invalid it throws an exception.
|
|
||||||
*/
|
|
||||||
public createUrl(): URL {
|
|
||||||
// Check if the query is valid
|
|
||||||
if (!this.validate()) {
|
|
||||||
throw new Error("Invalid query")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the URL
|
|
||||||
const url = new URL(urls.F95_LATEST_PHP);
|
|
||||||
url.searchParams.set("cmd", "list");
|
|
||||||
|
|
||||||
// Set the category
|
|
||||||
url.searchParams.set("cat", this.category);
|
|
||||||
|
|
||||||
// Add tags and prefixes
|
|
||||||
const parser = new PrefixParser();
|
|
||||||
for (const tag of parser.prefixesToIDs(this.tags)) {
|
|
||||||
url.searchParams.append("tags[]", tag.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const p of parser.prefixesToIDs(this.prefixes)) {
|
|
||||||
url.searchParams.append("prefixes[]", p.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the other values
|
|
||||||
url.searchParams.set("sort", this.sort.toString());
|
|
||||||
url.searchParams.set("page", this.page.toString());
|
|
||||||
if(this.date) url.searchParams.set("date", this.date.toString());
|
|
||||||
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
//#endregion Public methods
|
|
||||||
}
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Public modules from npm
|
||||||
|
import validator from 'class-validator';
|
||||||
|
|
||||||
|
// Module from files
|
||||||
|
import { IQuery, TCategory, TQueryInterface } from "../../interfaces";
|
||||||
|
import LatestSearchQuery, { TLatestOrder } from './latest-search-query';
|
||||||
|
import ThreadSearchQuery, { TThreadOrder } from './thread-search-query';
|
||||||
|
|
||||||
|
// Type definitions
|
||||||
|
/**
|
||||||
|
* Method of sorting results. Try to unify the two types of
|
||||||
|
* sorts in the "Latest" section and in the "Thread search"
|
||||||
|
* section. Being dynamic research, if a sorting type is not
|
||||||
|
* available, the replacement sort is chosen.
|
||||||
|
*
|
||||||
|
* `date`: Order based on the latest update
|
||||||
|
*
|
||||||
|
* `likes`: Order based on the number of likes received. Replacement: `replies`.
|
||||||
|
*
|
||||||
|
* `relevance`: Order based on the relevance of the result (or rating).
|
||||||
|
*
|
||||||
|
* `replies`: Order based on the number of answers to the thread. Replacement: `views`.
|
||||||
|
*
|
||||||
|
* `title`: Order based on the growing alphabetical order of the titles.
|
||||||
|
*
|
||||||
|
* `views`: Order based on the number of visits. Replacement: `replies`.
|
||||||
|
*/
|
||||||
|
type THandiworkOrder = "date" | "likes" | "relevance" | "replies" | "title" | "views";
|
||||||
|
|
||||||
|
export default class HandiworkSearchQuery implements IQuery {
|
||||||
|
|
||||||
|
//#region Private fields
|
||||||
|
static MIN_PAGE = 1;
|
||||||
|
//#endregion Private fields
|
||||||
|
|
||||||
|
//#region Properties
|
||||||
|
/**
|
||||||
|
* Keywords to use in the search.
|
||||||
|
*/
|
||||||
|
public keywords: string = "";
|
||||||
|
/**
|
||||||
|
* The results must be more recent than the date indicated.
|
||||||
|
*/
|
||||||
|
public newerThan: Date = null;
|
||||||
|
/**
|
||||||
|
* The results must be older than the date indicated.
|
||||||
|
*/
|
||||||
|
public olderThan: Date = null;
|
||||||
|
public includedTags: string[] = [];
|
||||||
|
/**
|
||||||
|
* Tags to exclude from the search.
|
||||||
|
*/
|
||||||
|
public excludedTags: string[] = [];
|
||||||
|
public includedPrefixes: string[];
|
||||||
|
public category: TCategory;
|
||||||
|
/**
|
||||||
|
* Results presentation order.
|
||||||
|
*/
|
||||||
|
public order: THandiworkOrder = "relevance";
|
||||||
|
@validator.IsInt({
|
||||||
|
message: "$property expect an integer, received $value"
|
||||||
|
})
|
||||||
|
@validator.Min(HandiworkSearchQuery.MIN_PAGE, {
|
||||||
|
message: "The minimum $property value must be $constraint1, received $value"
|
||||||
|
})
|
||||||
|
public page: number = 1;
|
||||||
|
itype: TQueryInterface = "HandiworkSearchQuery";
|
||||||
|
//#endregion Properties
|
||||||
|
|
||||||
|
//#region Public methods
|
||||||
|
/**
|
||||||
|
* Select what kind of search should be
|
||||||
|
* performed based on the properties of
|
||||||
|
* the query.
|
||||||
|
*/
|
||||||
|
public selectSearchType(): "latest" | "thread" {
|
||||||
|
// Local variables
|
||||||
|
const MAX_TAGS_LATEST_SEARCH = 5;
|
||||||
|
const DEFAULT_SEARCH_TYPE = "latest";
|
||||||
|
|
||||||
|
// If the keywords are set or the number
|
||||||
|
// of included tags is greather than 5,
|
||||||
|
// we must perform a thread search
|
||||||
|
if (this.keywords || this.includedTags.length > MAX_TAGS_LATEST_SEARCH) return "thread";
|
||||||
|
|
||||||
|
return DEFAULT_SEARCH_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public validate(): boolean {
|
||||||
|
return validator.validateSync(this).length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public createURL(): URL {
|
||||||
|
// Local variables
|
||||||
|
let query: LatestSearchQuery | ThreadSearchQuery = null;
|
||||||
|
|
||||||
|
// Check if the query is valid
|
||||||
|
if (!this.validate()) {
|
||||||
|
throw new Error(`Invalid query: ${validator.validateSync(this).join("\n")}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the query
|
||||||
|
if (this.selectSearchType() === "latest") query = this.cast<LatestSearchQuery>();
|
||||||
|
else query = this.cast<ThreadSearchQuery>();
|
||||||
|
|
||||||
|
return query.createURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
public cast<T extends IQuery>(): T {
|
||||||
|
// Local variables
|
||||||
|
let returnValue = null;
|
||||||
|
|
||||||
|
// Cast the query
|
||||||
|
const query:T = {} as IQuery as T;
|
||||||
|
|
||||||
|
// Convert the query
|
||||||
|
if (query.itype === "LatestSearchQuery") returnValue = this.castToLatest();
|
||||||
|
else if (query.itype === "ThreadSearchQuery") returnValue = this.castToThread();
|
||||||
|
else returnValue = this as HandiworkSearchQuery;
|
||||||
|
|
||||||
|
// Cast the result to T
|
||||||
|
return returnValue as T;
|
||||||
|
}
|
||||||
|
//#endregion Public methods
|
||||||
|
|
||||||
|
//#region Private methods
|
||||||
|
private castToLatest(): LatestSearchQuery {
|
||||||
|
// Cast the basic query object
|
||||||
|
const query: LatestSearchQuery = this as IQuery as LatestSearchQuery;
|
||||||
|
let orderFilter = this.order as string;
|
||||||
|
query.itype = "LatestSearchQuery";
|
||||||
|
|
||||||
|
// Adapt order filter
|
||||||
|
if (orderFilter === "relevance") orderFilter = "rating";
|
||||||
|
else if (orderFilter === "replies") orderFilter = "views";
|
||||||
|
query.order = orderFilter as TLatestOrder;
|
||||||
|
|
||||||
|
// Adapt date
|
||||||
|
if (this.newerThan) query.date = query.findNearestDate(this.newerThan);
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
private castToThread(): ThreadSearchQuery {
|
||||||
|
// Cast the basic query object
|
||||||
|
const query: ThreadSearchQuery = this as IQuery as ThreadSearchQuery;
|
||||||
|
let orderFilter = this.order as string;
|
||||||
|
|
||||||
|
// Set common values
|
||||||
|
query.excludedTags = this.excludedTags;
|
||||||
|
query.newerThan = this.newerThan;
|
||||||
|
query.olderThan = this.olderThan;
|
||||||
|
query.onlyTitles = true;
|
||||||
|
query.keywords = this.keywords;
|
||||||
|
|
||||||
|
// Adapt order filter
|
||||||
|
if (orderFilter === "likes" || orderFilter === "title") orderFilter = "relevance";
|
||||||
|
query.order = orderFilter as TThreadOrder;
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
}
|
|
@ -2,12 +2,12 @@
|
||||||
import validator from 'class-validator';
|
import validator from 'class-validator';
|
||||||
|
|
||||||
// Modules from file
|
// Modules from file
|
||||||
import { urls } from "../constants/url.js";
|
import { urls } from "../../constants/url.js";
|
||||||
import PrefixParser from './prefix-parser.js';
|
import PrefixParser from '../prefix-parser.js';
|
||||||
import { IQuery, TCategory } from "../interfaces";
|
import { IQuery, TCategory, TQueryInterface } from "../../interfaces";
|
||||||
|
|
||||||
// Type definitions
|
// Type definitions
|
||||||
type TOrder = "date" | "likes" | "views" | "title" | "rating";
|
export type TLatestOrder = "date" | "likes" | "views" | "title" | "rating";
|
||||||
type TDate = 365 | 180 | 90 | 30 | 14 | 7 | 3 | 1;
|
type TDate = 365 | 180 | 90 | 30 | 14 | 7 | 3 | 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +27,7 @@ export default class LatestSearchQuery implements IQuery {
|
||||||
*
|
*
|
||||||
* Default: `date`.
|
* Default: `date`.
|
||||||
*/
|
*/
|
||||||
public order: TOrder = 'date';
|
public order: TLatestOrder = 'date';
|
||||||
/**
|
/**
|
||||||
* Date limit in days, to be understood as "less than".
|
* Date limit in days, to be understood as "less than".
|
||||||
* Use `1` to indicate "today" or `null` to indicate "anytime".
|
* Use `1` to indicate "today" or `null` to indicate "anytime".
|
||||||
|
@ -40,7 +40,6 @@ export default class LatestSearchQuery implements IQuery {
|
||||||
message: "Too many tags: $value instead of $constraint1"
|
message: "Too many tags: $value instead of $constraint1"
|
||||||
})
|
})
|
||||||
public includedTags: string[] = [];
|
public includedTags: string[] = [];
|
||||||
|
|
||||||
public includedPrefixes: string[] = [];
|
public includedPrefixes: string[] = [];
|
||||||
|
|
||||||
@validator.IsInt({
|
@validator.IsInt({
|
||||||
|
@ -50,24 +49,19 @@ export default class LatestSearchQuery implements IQuery {
|
||||||
message: "The minimum $property value must be $constraint1, received $value"
|
message: "The minimum $property value must be $constraint1, received $value"
|
||||||
})
|
})
|
||||||
public page = LatestSearchQuery.MIN_PAGE;
|
public page = LatestSearchQuery.MIN_PAGE;
|
||||||
|
itype: TQueryInterface = "LatestSearchQuery";
|
||||||
//#endregion Properties
|
//#endregion Properties
|
||||||
|
|
||||||
//#region Public methods
|
//#region Public methods
|
||||||
/**
|
|
||||||
* Verify that the query values are valid.
|
|
||||||
*/
|
|
||||||
public validate(): boolean {
|
public validate(): boolean {
|
||||||
return validator.validateSync(this).length === 0;
|
return validator.validateSync(this).length === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* From the query values it generates the corresponding URL for the platform.
|
|
||||||
* If the query is invalid it throws an exception.
|
|
||||||
*/
|
|
||||||
public createURL(): URL {
|
public createURL(): URL {
|
||||||
// Check if the query is valid
|
// Check if the query is valid
|
||||||
if (!this.validate()) {
|
if (!this.validate()) {
|
||||||
throw new Error("Invalid query")
|
throw new Error(`Invalid query: ${validator.validateSync(this).join("\n")}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the URL
|
// Create the URL
|
||||||
|
@ -94,5 +88,32 @@ export default class LatestSearchQuery implements IQuery {
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public findNearestDate(d: Date): TDate {
|
||||||
|
// Find the difference between today and the passed date
|
||||||
|
const diff = this.dateDiffInDays(new Date(), d);
|
||||||
|
|
||||||
|
// Find the closest valid value in the array
|
||||||
|
const closest = [365, 180, 90, 30, 14, 7, 3, 1].reduce(function (prev, curr) {
|
||||||
|
return (Math.abs(curr - diff) < Math.abs(prev - diff) ? curr : prev);
|
||||||
|
});
|
||||||
|
|
||||||
|
return closest as TDate;
|
||||||
|
}
|
||||||
//#endregion Public methods
|
//#endregion Public methods
|
||||||
|
|
||||||
|
//#region Private methods
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private dateDiffInDays(a: Date, b: Date) {
|
||||||
|
const MS_PER_DAY = 1000 * 60 * 60 * 24;
|
||||||
|
|
||||||
|
// Discard the time and time-zone information.
|
||||||
|
const utc1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
|
||||||
|
const utc2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
|
||||||
|
|
||||||
|
return Math.floor((utc2 - utc1) / MS_PER_DAY);
|
||||||
|
}
|
||||||
|
//#endregion Private methodss
|
||||||
}
|
}
|
|
@ -0,0 +1,155 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Public modules from npm
|
||||||
|
import validator from 'class-validator';
|
||||||
|
|
||||||
|
// Module from files
|
||||||
|
import { IQuery, TCategory, TQueryInterface } from "../interfaces";
|
||||||
|
import { urls } from "../constants/url";
|
||||||
|
import PrefixParser from "./prefix-parser";
|
||||||
|
|
||||||
|
// Type definitions
|
||||||
|
export type TThreadOrder = "relevance" | "date" | "last_update" | "replies";
|
||||||
|
|
||||||
|
export default class ThreadSearchQuery implements IQuery {
|
||||||
|
|
||||||
|
//#region Private fields
|
||||||
|
static MIN_PAGE = 1;
|
||||||
|
//#endregion Private fields
|
||||||
|
|
||||||
|
//#region Properties
|
||||||
|
/**
|
||||||
|
* Keywords to use in the search.
|
||||||
|
*/
|
||||||
|
public keywords: string = "";
|
||||||
|
/**
|
||||||
|
* Indicates to search by checking only the thread titles and not the content.
|
||||||
|
*/
|
||||||
|
public onlyTitles: boolean = false;
|
||||||
|
/**
|
||||||
|
* The results must be more recent than the date indicated.
|
||||||
|
*/
|
||||||
|
public newerThan: Date = null;
|
||||||
|
/**
|
||||||
|
* The results must be older than the date indicated.
|
||||||
|
*/
|
||||||
|
public olderThan: Date = null;
|
||||||
|
public includedTags: string[] = [];
|
||||||
|
/**
|
||||||
|
* Tags to exclude from the search.
|
||||||
|
*/
|
||||||
|
public excludedTags: string[] = [];
|
||||||
|
/**
|
||||||
|
* Minimum number of answers that the thread must possess.
|
||||||
|
*/
|
||||||
|
public minimumReplies: number = 0;
|
||||||
|
public includedPrefixes: string[];
|
||||||
|
public category: TCategory;
|
||||||
|
/**
|
||||||
|
* Results presentation order.
|
||||||
|
*/
|
||||||
|
public order: TThreadOrder = "relevance";
|
||||||
|
@validator.IsInt({
|
||||||
|
message: "$property expect an integer, received $value"
|
||||||
|
})
|
||||||
|
@validator.Min(ThreadSearchQuery.MIN_PAGE, {
|
||||||
|
message: "The minimum $property value must be $constraint1, received $value"
|
||||||
|
})
|
||||||
|
public page: number = 1;
|
||||||
|
itype: TQueryInterface = "ThreadSearchQuery";
|
||||||
|
//#endregion Properties
|
||||||
|
|
||||||
|
//#region Public methods
|
||||||
|
|
||||||
|
public validate(): boolean {
|
||||||
|
return validator.validateSync(this).length === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public createURL(): URL {
|
||||||
|
// Check if the query is valid
|
||||||
|
if (!this.validate()) {
|
||||||
|
throw new Error(`Invalid query: ${validator.validateSync(this).join("\n")}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the URL
|
||||||
|
const url = new URL(urls.F95_SEARCH_URL);
|
||||||
|
|
||||||
|
// Specifiy if only the title should be searched
|
||||||
|
if (this.onlyTitles) url.searchParams.set("c[title_only]", "1");
|
||||||
|
|
||||||
|
// Add keywords
|
||||||
|
const encodedKeywords = this.keywords ? encodeURIComponent(this.keywords) : "*";
|
||||||
|
url.searchParams.set("q", encodedKeywords);
|
||||||
|
|
||||||
|
// Specify the scope of the search (only "threads/post")
|
||||||
|
url.searchParams.set("t", "post");
|
||||||
|
|
||||||
|
// Set the dates
|
||||||
|
if (this.newerThan) {
|
||||||
|
const date = this.convertShortDate(this.newerThan);
|
||||||
|
url.searchParams.set("c[newer_than]", date);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.olderThan) {
|
||||||
|
const date = this.convertShortDate(this.olderThan);
|
||||||
|
url.searchParams.set("c[older_than]", date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set included and excluded tags
|
||||||
|
// The tags are first joined with a comma, then encoded to URI
|
||||||
|
const includedTags = encodeURIComponent(this.includedTags.join(","));
|
||||||
|
const excludedTags = encodeURIComponent(this.excludedTags.join(","));
|
||||||
|
url.searchParams.set("c[tags]", includedTags);
|
||||||
|
url.searchParams.set("c[excludeTags]", excludedTags);
|
||||||
|
|
||||||
|
// Set minimum reply number
|
||||||
|
url.searchParams.set("c[min_reply_count]", this.minimumReplies.toString());
|
||||||
|
|
||||||
|
// Add prefixes
|
||||||
|
const parser = new PrefixParser();
|
||||||
|
const ids = parser.prefixesToIDs(this.includedPrefixes);
|
||||||
|
for (let i = 0; i < ids.length; i++) {
|
||||||
|
const name = `c[prefixes][${i}]`;
|
||||||
|
url.searchParams.set(name, ids[i].toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the category
|
||||||
|
const catID = this.categoryToID(this.category).toString();
|
||||||
|
url.searchParams.set("c[child_nodes]", "1"); // Always set
|
||||||
|
url.searchParams.set("c[nodes][0]", catID);
|
||||||
|
|
||||||
|
// Set the other values
|
||||||
|
url.searchParams.set("o", this.order.toString());
|
||||||
|
url.searchParams.set("page", this.page.toString());
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
//#endregion Public methods
|
||||||
|
|
||||||
|
//#region Private methods
|
||||||
|
/**
|
||||||
|
* Convert a date in the YYYY-MM-DD format taking into account the time zone.
|
||||||
|
*/
|
||||||
|
private convertShortDate(d: Date): string {
|
||||||
|
const offset = d.getTimezoneOffset()
|
||||||
|
d = new Date(d.getTime() - (offset * 60 * 1000))
|
||||||
|
return d.toISOString().split('T')[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the unique ID of the selected category.
|
||||||
|
*/
|
||||||
|
private categoryToID(category: TCategory): number {
|
||||||
|
const catMap = {
|
||||||
|
"games": 1,
|
||||||
|
"mods": 41,
|
||||||
|
"comics": 40,
|
||||||
|
"animations": 94,
|
||||||
|
"assets": 95,
|
||||||
|
}
|
||||||
|
|
||||||
|
return catMap[category as string];
|
||||||
|
}
|
||||||
|
//#endregion Private methods
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue